diff --git a/pom.xml b/pom.xml
index 1c0d6b3d51..7e48649b9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
   <groupId>org.bukkit</groupId>
   <artifactId>craftbukkit</artifactId>
   <packaging>jar</packaging>
-  <version>1.1-R6-SNAPSHOT</version>
+  <version>1.2.2-R0-SNAPSHOT</version>
   <name>CraftBukkit</name>
   <url>http://www.bukkit.org</url>
 
@@ -51,14 +51,14 @@
     <dependency>
       <groupId>org.bukkit</groupId>
       <artifactId>bukkit</artifactId>
-      <version>1.1-R6</version>
+      <version>1.2.2-R0-SNAPSHOT</version>
       <type>jar</type>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.bukkit</groupId>
       <artifactId>minecraft-server</artifactId>
-      <version>1.1_02</version>
+      <version>1.2.2</version>
       <type>jar</type>
       <scope>compile</scope>
     </dependency>
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index f06b4359df..f73a88af4e 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -14,33 +14,31 @@ public class Block {
     public static final StepSound j = new StepSoundStone("stone", 1.0F, 1.0F);
     public static final StepSound k = new StepSound("cloth", 1.0F, 1.0F);
     public static final StepSound l = new StepSoundSand("sand", 1.0F, 1.0F);
-    public static final Block[] byId = new Block[256];
-    public static final boolean[] n = new boolean[256];
-    public static final boolean[] o = new boolean[256];
-    public static final boolean[] isTileEntity = new boolean[256];
-    public static final int[] lightBlock = new int[256];
-    public static final boolean[] r = new boolean[256];
-    public static final int[] lightEmission = new int[256];
-    public static final boolean[] t = new boolean[256];
-    public static boolean[] u = new boolean[256];
+    public static final Block[] byId = new Block[4096];
+    public static final boolean[] n = new boolean[4096];
+    public static final int[] lightBlock = new int[4096];
+    public static final boolean[] p = new boolean[4096];
+    public static final int[] lightEmission = new int[4096];
+    public static final boolean[] r = new boolean[4096];
+    public static boolean[] s = new boolean[4096];
     public static final Block STONE = (new BlockStone(1, 1)).c(1.5F).b(10.0F).a(h).a("stone");
     public static final BlockGrass GRASS = (BlockGrass) (new BlockGrass(2)).c(0.6F).a(g).a("grass");
     public static final Block DIRT = (new BlockDirt(3, 2)).c(0.5F).a(f).a("dirt");
     public static final Block COBBLESTONE = (new Block(4, 16, Material.STONE)).c(2.0F).b(10.0F).a(h).a("stonebrick");
     public static final Block WOOD = (new Block(5, 4, Material.WOOD)).c(2.0F).b(5.0F).a(e).a("wood").i();
     public static final Block SAPLING = (new BlockSapling(6, 15)).c(0.0F).a(g).a("sapling").i();
-    public static final Block BEDROCK = (new Block(7, 17, Material.STONE)).k().b(6000000.0F).a(h).a("bedrock").p();
-    public static final Block WATER = (new BlockFlowing(8, Material.WATER)).c(100.0F).g(3).a("water").p().i();
-    public static final Block STATIONARY_WATER = (new BlockStationary(9, Material.WATER)).c(100.0F).g(3).a("water").p().i();
-    public static final Block LAVA = (new BlockFlowing(10, Material.LAVA)).c(0.0F).a(1.0F).g(255).a("lava").p().i();
-    public static final Block STATIONARY_LAVA = (new BlockStationary(11, Material.LAVA)).c(100.0F).a(1.0F).g(255).a("lava").p().i();
+    public static final Block BEDROCK = (new Block(7, 17, Material.STONE)).k().b(6000000.0F).a(h).a("bedrock").r();
+    public static final Block WATER = (new BlockFlowing(8, Material.WATER)).c(100.0F).f(3).a("water").r().i();
+    public static final Block STATIONARY_WATER = (new BlockStationary(9, Material.WATER)).c(100.0F).f(3).a("water").r().i();
+    public static final Block LAVA = (new BlockFlowing(10, Material.LAVA)).c(0.0F).a(1.0F).f(255).a("lava").r().i();
+    public static final Block STATIONARY_LAVA = (new BlockStationary(11, Material.LAVA)).c(100.0F).a(1.0F).f(255).a("lava").r().i();
     public static final Block SAND = (new BlockSand(12, 18)).c(0.5F).a(l).a("sand");
     public static final Block GRAVEL = (new BlockGravel(13, 19)).c(0.6F).a(f).a("gravel");
     public static final Block GOLD_ORE = (new BlockOre(14, 32)).c(3.0F).b(5.0F).a(h).a("oreGold");
     public static final Block IRON_ORE = (new BlockOre(15, 33)).c(3.0F).b(5.0F).a(h).a("oreIron");
     public static final Block COAL_ORE = (new BlockOre(16, 34)).c(3.0F).b(5.0F).a(h).a("oreCoal");
     public static final Block LOG = (new BlockLog(17)).c(2.0F).a(e).a("log").i();
-    public static final BlockLeaves LEAVES = (BlockLeaves) (new BlockLeaves(18, 52)).c(0.2F).g(1).a(g).a("leaves").i();
+    public static final BlockLeaves LEAVES = (BlockLeaves) (new BlockLeaves(18, 52)).c(0.2F).f(1).a(g).a("leaves").i();
     public static final Block SPONGE = (new BlockSponge(19)).c(0.6F).a(g).a("sponge");
     public static final Block GLASS = (new BlockGlass(20, 49, Material.SHATTERABLE, false)).c(0.3F).a(j).a("glass");
     public static final Block LAPIS_ORE = (new BlockOre(21, 160)).c(3.0F).b(5.0F).a(h).a("oreLapis");
@@ -48,11 +46,11 @@ public class Block {
     public static final Block DISPENSER = (new BlockDispenser(23)).c(3.5F).a(h).a("dispenser").i();
     public static final Block SANDSTONE = (new BlockSandStone(24)).a(h).c(0.8F).a("sandStone");
     public static final Block NOTE_BLOCK = (new BlockNote(25)).c(0.8F).a("musicBlock").i();
-    public static final Block BED = (new BlockBed(26)).c(0.2F).a("bed").p().i();
+    public static final Block BED = (new BlockBed(26)).c(0.2F).a("bed").r().i();
     public static final Block GOLDEN_RAIL = (new BlockMinecartTrack(27, 179, true)).c(0.7F).a(i).a("goldenRail").i();
     public static final Block DETECTOR_RAIL = (new BlockMinecartDetector(28, 195)).c(0.7F).a(i).a("detectorRail").i();
     public static final Block PISTON_STICKY = (new BlockPiston(29, 106, true)).a("pistonStickyBase").i();
-    public static final Block WEB = (new BlockWeb(30, 11)).g(1).c(4.0F).a("web");
+    public static final Block WEB = (new BlockWeb(30, 11)).f(1).c(4.0F).a("web");
     public static final BlockLongGrass LONG_GRASS = (BlockLongGrass) (new BlockLongGrass(31, 39)).c(0.0F).a(g).a("tallgrass");
     public static final BlockDeadBush DEAD_BUSH = (BlockDeadBush) (new BlockDeadBush(32, 55)).c(0.0F).a(g).a("deadbush");
     public static final Block PISTON = (new BlockPiston(33, 107, false)).a("pistonBase").i();
@@ -73,39 +71,39 @@ public class Block {
     public static final Block MOSSY_COBBLESTONE = (new Block(48, 36, Material.STONE)).c(2.0F).b(10.0F).a(h).a("stoneMoss");
     public static final Block OBSIDIAN = (new BlockObsidian(49, 37)).c(50.0F).b(2000.0F).a(h).a("obsidian");
     public static final Block TORCH = (new BlockTorch(50, 80)).c(0.0F).a(0.9375F).a(e).a("torch").i();
-    public static final BlockFire FIRE = (BlockFire) (new BlockFire(51, 31)).c(0.0F).a(1.0F).a(e).a("fire").p();
-    public static final Block MOB_SPAWNER = (new BlockMobSpawner(52, 65)).c(5.0F).a(i).a("mobSpawner").p();
+    public static final BlockFire FIRE = (BlockFire) (new BlockFire(51, 31)).c(0.0F).a(1.0F).a(e).a("fire").r();
+    public static final Block MOB_SPAWNER = (new BlockMobSpawner(52, 65)).c(5.0F).a(i).a("mobSpawner").r();
     public static final Block WOOD_STAIRS = (new BlockStairs(53, WOOD)).a("stairsWood").i();
     public static final Block CHEST = (new BlockChest(54)).c(2.5F).a(e).a("chest").i();
-    public static final Block REDSTONE_WIRE = (new BlockRedstoneWire(55, 164)).c(0.0F).a(d).a("redstoneDust").p().i();
+    public static final Block REDSTONE_WIRE = (new BlockRedstoneWire(55, 164)).c(0.0F).a(d).a("redstoneDust").r().i();
     public static final Block DIAMOND_ORE = (new BlockOre(56, 50)).c(3.0F).b(5.0F).a(h).a("oreDiamond");
     public static final Block DIAMOND_BLOCK = (new BlockOreBlock(57, 24)).c(5.0F).b(10.0F).a(i).a("blockDiamond");
     public static final Block WORKBENCH = (new BlockWorkbench(58)).c(2.5F).a(e).a("workbench");
-    public static final Block CROPS = (new BlockCrops(59, 88)).c(0.0F).a(g).a("crops").p().i();
+    public static final Block CROPS = (new BlockCrops(59, 88)).c(0.0F).a(g).a("crops").r().i();
     public static final Block SOIL = (new BlockSoil(60)).c(0.6F).a(f).a("farmland").i();
     public static final Block FURNACE = (new BlockFurnace(61, false)).c(3.5F).a(h).a("furnace").i();
     public static final Block BURNING_FURNACE = (new BlockFurnace(62, true)).c(3.5F).a(h).a(0.875F).a("furnace").i();
-    public static final Block SIGN_POST = (new BlockSign(63, TileEntitySign.class, true)).c(1.0F).a(e).a("sign").p().i();
-    public static final Block WOODEN_DOOR = (new BlockDoor(64, Material.WOOD)).c(3.0F).a(e).a("doorWood").p().i();
+    public static final Block SIGN_POST = (new BlockSign(63, TileEntitySign.class, true)).c(1.0F).a(e).a("sign").r().i();
+    public static final Block WOODEN_DOOR = (new BlockDoor(64, Material.WOOD)).c(3.0F).a(e).a("doorWood").r().i();
     public static final Block LADDER = (new BlockLadder(65, 83)).c(0.4F).a(e).a("ladder").i();
     public static final Block RAILS = (new BlockMinecartTrack(66, 128, false)).c(0.7F).a(i).a("rail").i();
     public static final Block COBBLESTONE_STAIRS = (new BlockStairs(67, COBBLESTONE)).a("stairsStone").i();
-    public static final Block WALL_SIGN = (new BlockSign(68, TileEntitySign.class, false)).c(1.0F).a(e).a("sign").p().i();
+    public static final Block WALL_SIGN = (new BlockSign(68, TileEntitySign.class, false)).c(1.0F).a(e).a("sign").r().i();
     public static final Block LEVER = (new BlockLever(69, 96)).c(0.5F).a(e).a("lever").i();
     public static final Block STONE_PLATE = (new BlockPressurePlate(70, STONE.textureId, EnumMobType.MOBS, Material.STONE)).c(0.5F).a(h).a("pressurePlate").i();
-    public static final Block IRON_DOOR_BLOCK = (new BlockDoor(71, Material.ORE)).c(5.0F).a(i).a("doorIron").p().i();
+    public static final Block IRON_DOOR_BLOCK = (new BlockDoor(71, Material.ORE)).c(5.0F).a(i).a("doorIron").r().i();
     public static final Block WOOD_PLATE = (new BlockPressurePlate(72, WOOD.textureId, EnumMobType.EVERYTHING, Material.WOOD)).c(0.5F).a(e).a("pressurePlate").i();
     public static final Block REDSTONE_ORE = (new BlockRedstoneOre(73, 51, false)).c(3.0F).b(5.0F).a(h).a("oreRedstone").i();
     public static final Block GLOWING_REDSTONE_ORE = (new BlockRedstoneOre(74, 51, true)).a(0.625F).c(3.0F).b(5.0F).a(h).a("oreRedstone").i();
     public static final Block REDSTONE_TORCH_OFF = (new BlockRedstoneTorch(75, 115, false)).c(0.0F).a(e).a("notGate").i();
     public static final Block REDSTONE_TORCH_ON = (new BlockRedstoneTorch(76, 99, true)).c(0.0F).a(0.5F).a(e).a("notGate").i();
     public static final Block STONE_BUTTON = (new BlockButton(77, STONE.textureId)).c(0.5F).a(h).a("button").i();
-    public static final Block SNOW = (new BlockSnow(78, 66)).c(0.1F).a(k).a("snow").g(0);
-    public static final Block ICE = (new BlockIce(79, 67)).c(0.5F).g(3).a(j).a("ice");
+    public static final Block SNOW = (new BlockSnow(78, 66)).c(0.1F).a(k).a("snow").f(0);
+    public static final Block ICE = (new BlockIce(79, 67)).c(0.5F).f(3).a(j).a("ice");
     public static final Block SNOW_BLOCK = (new BlockSnowBlock(80, 66)).c(0.2F).a(k).a("snow");
     public static final Block CACTUS = (new BlockCactus(81, 70)).c(0.4F).a(k).a("cactus");
     public static final Block CLAY = (new BlockClay(82, 72)).c(0.6F).a(f).a("clay");
-    public static final Block SUGAR_CANE_BLOCK = (new BlockReed(83, 73)).c(0.0F).a(g).a("reeds").p();
+    public static final Block SUGAR_CANE_BLOCK = (new BlockReed(83, 73)).c(0.0F).a(g).a("reeds").r();
     public static final Block JUKEBOX = (new BlockJukeBox(84, 74)).c(2.0F).b(10.0F).a(h).a("jukebox").i();
     public static final Block FENCE = (new BlockFence(85, 4)).c(2.0F).b(5.0F).a(e).a("fence");
     public static final Block PUMPKIN = (new BlockPumpkin(86, 102, false)).c(1.0F).a(e).a("pumpkin").i();
@@ -114,11 +112,11 @@ public class Block {
     public static final Block GLOWSTONE = (new BlockLightStone(89, 105, Material.SHATTERABLE)).c(0.3F).a(j).a(1.0F).a("lightgem");
     public static final BlockPortal PORTAL = (BlockPortal) (new BlockPortal(90, 14)).c(-1.0F).a(j).a(0.75F).a("portal");
     public static final Block JACK_O_LANTERN = (new BlockPumpkin(91, 102, true)).c(1.0F).a(e).a(1.0F).a("litpumpkin").i();
-    public static final Block CAKE_BLOCK = (new BlockCake(92, 121)).c(0.5F).a(k).a("cake").p().i();
-    public static final Block DIODE_OFF = (new BlockDiode(93, false)).c(0.0F).a(e).a("diode").p().i();
-    public static final Block DIODE_ON = (new BlockDiode(94, true)).c(0.0F).a(0.625F).a(e).a("diode").p().i();
+    public static final Block CAKE_BLOCK = (new BlockCake(92, 121)).c(0.5F).a(k).a("cake").r().i();
+    public static final Block DIODE_OFF = (new BlockDiode(93, false)).c(0.0F).a(e).a("diode").r().i();
+    public static final Block DIODE_ON = (new BlockDiode(94, true)).c(0.0F).a(0.625F).a(e).a("diode").r().i();
     public static final Block LOCKED_CHEST = (new BlockLockedChest(95)).c(0.0F).a(1.0F).a(e).a("lockedchest").a(true).i();
-    public static final Block TRAP_DOOR = (new BlockTrapdoor(96, Material.WOOD)).c(3.0F).a(e).a("trapdoor").p().i();
+    public static final Block TRAP_DOOR = (new BlockTrapdoor(96, Material.WOOD)).c(3.0F).a(e).a("trapdoor").r().i();
     public static final Block MONSTER_EGGS = (new BlockMonsterEggs(97)).c(0.75F);
     public static final Block SMOOTH_BRICK = (new BlockSmoothBrick(98)).c(1.5F).b(10.0F).a(h).a("stonebricksmooth");
     public static final Block BIG_MUSHROOM_1 = (new BlockHugeMushroom(99, Material.WOOD, 142, 0)).c(0.2F).a(e).a("mushroom").i();
@@ -145,12 +143,16 @@ public class Block {
     public static final Block ENDER_PORTAL_FRAME = (new BlockEnderPortalFrame(120)).a(j).a(0.125F).c(-1.0F).a("endPortalFrame").i().b(6000000.0F);
     public static final Block WHITESTONE = (new Block(121, 175, Material.STONE)).c(3.0F).b(15.0F).a(h).a("whiteStone");
     public static final Block DRAGON_EGG = (new BlockDragonEgg(122, 167)).c(3.0F).b(15.0F).a(h).a(0.125F).a("dragonEgg");
+    public static final Block REDSTONE_LAMP_OFF = (new BlockRedstoneLamp(123, false)).c(0.3F).a(j).a("redstoneLight");
+    public static final Block REDSTONE_LAMP_ON = (new BlockRedstoneLamp(124, true)).c(0.3F).a(j).a("redstoneLight");
     public int textureId;
     public final int id;
     protected float strength;
     protected float durability;
     protected boolean bR;
     protected boolean bS;
+    protected boolean bT;
+    protected boolean isTileEntity;
     public double minX;
     public double minY;
     public double minZ;
@@ -158,7 +160,7 @@ public class Block {
     public double maxY;
     public double maxZ;
     public StepSound stepSound;
-    public float ca;
+    public float cc;
     public final Material material;
     public float frictionFactor;
     private String name;
@@ -167,7 +169,7 @@ public class Block {
         this.bR = true;
         this.bS = true;
         this.stepSound = d;
-        this.ca = 1.0F;
+        this.cc = 1.0F;
         this.frictionFactor = 0.6F;
         if (byId[i] != null) {
             throw new IllegalArgumentException("Slot " + i + " is already occupied by " + byId[i] + " when adding " + this);
@@ -176,15 +178,14 @@ public class Block {
             byId[i] = this;
             this.id = i;
             this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
-            o[i] = this.a();
+            n[i] = this.a();
             lightBlock[i] = this.a() ? 255 : 0;
-            r[i] = !material.blocksLight();
-            isTileEntity[i] = false;
+            p[i] = !material.blocksLight();
         }
     }
 
     protected Block i() {
-        t[this.id] = true;
+        r[this.id] = true;
         return this;
     }
 
@@ -200,7 +201,7 @@ public class Block {
         return this;
     }
 
-    protected Block g(int i) {
+    protected Block f(int i) {
         lightBlock[this.id] = i;
         return this;
     }
@@ -215,10 +216,20 @@ public class Block {
         return this;
     }
 
+    public static boolean g(int i) {
+        Block block = byId[i];
+
+        return block == null ? false : block.material.j() && block.b();
+    }
+
     public boolean b() {
         return true;
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        return !this.material.isSolid();
+    }
+
     public int c() {
         return 0;
     }
@@ -242,10 +253,18 @@ public class Block {
     }
 
     protected Block a(boolean flag) {
-        n[this.id] = flag;
+        this.bT = flag;
         return this;
     }
 
+    public boolean m() {
+        return this.bT;
+    }
+
+    public boolean n() {
+        return this.isTileEntity;
+    }
+
     public void a(float f, float f1, float f2, float f3, float f4, float f5) {
         this.minX = (double) f;
         this.minY = (double) f1;
@@ -284,10 +303,10 @@ public class Block {
     }
 
     public boolean a(int i, boolean flag) {
-        return this.x_();
+        return this.F_();
     }
 
-    public boolean x_() {
+    public boolean F_() {
         return true;
     }
 
@@ -510,7 +529,7 @@ public class Block {
     public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
         entityhuman.a(StatisticList.C[this.id], 1);
         entityhuman.c(0.025F);
-        if (this.b() && !isTileEntity[this.id] && EnchantmentManager.hasSilkTouchEnchantment(entityhuman.inventory)) {
+        if (this.b() && !this.isTileEntity && EnchantmentManager.hasSilkTouchEnchantment(entityhuman.inventory)) {
             ItemStack itemstack = this.a_(l);
 
             if (itemstack != null) {
@@ -549,20 +568,20 @@ public class Block {
     }
 
     public String getName() {
-        return LocaleI18n.get(this.n() + ".name");
+        return LocaleI18n.get(this.p() + ".name");
     }
 
-    public String n() {
+    public String p() {
         return this.name;
     }
 
     public void a(World world, int i, int j, int k, int l, int i1) {}
 
-    public boolean o() {
+    public boolean q() {
         return this.bS;
     }
 
-    protected Block p() {
+    protected Block r() {
         this.bS = false;
         return this;
     }
@@ -609,11 +628,15 @@ public class Block {
                     flag = true;
                 }
 
-                u[i] = flag;
+                if (p[i]) {
+                    flag = true;
+                }
+
+                s[i] = flag;
             }
         }
 
-        r[0] = true;
+        p[0] = true;
         StatisticList.b();
     }
 
diff --git a/src/main/java/net/minecraft/server/BlockDispenser.java b/src/main/java/net/minecraft/server/BlockDispenser.java
index c9460d08d5..a00dc3cfdb 100644
--- a/src/main/java/net/minecraft/server/BlockDispenser.java
+++ b/src/main/java/net/minecraft/server/BlockDispenser.java
@@ -38,19 +38,19 @@ public class BlockDispenser extends BlockContainer {
             int k1 = world.getTypeId(i + 1, j, k);
             byte b0 = 3;
 
-            if (Block.o[l] && !Block.o[i1]) {
+            if (Block.n[l] && !Block.n[i1]) {
                 b0 = 3;
             }
 
-            if (Block.o[i1] && !Block.o[l]) {
+            if (Block.n[i1] && !Block.n[l]) {
                 b0 = 2;
             }
 
-            if (Block.o[j1] && !Block.o[k1]) {
+            if (Block.n[j1] && !Block.n[k1]) {
                 b0 = 5;
             }
 
-            if (Block.o[k1] && !Block.o[j1]) {
+            if (Block.n[k1] && !Block.n[j1]) {
                 b0 = 4;
             }
 
@@ -167,6 +167,20 @@ public class BlockDispenser extends BlockContainer {
                     entitypotion.a((double) b0, 0.10000000149011612D, (double) b1, 1.375F, 3.0F);
                     world.addEntity(entitypotion);
                     world.triggerEffect(1002, i, j, k, 0);
+                } else if (itemstack.id == Item.EXP_BOTTLE.id) {
+                    EntityThrownExpBottle entitythrownexpbottle = new EntityThrownExpBottle(world, d0, d1, d2);
+
+                    entitythrownexpbottle.a((double) b0, 0.10000000149011612D, (double) b1, 1.375F, 3.0F);
+                    world.addEntity(entitythrownexpbottle);
+                    world.triggerEffect(1002, i, j, k, 0);
+                } else if (itemstack.id == Item.MONSTER_EGG.id) {
+                    ItemMonsterEgg.a(world, itemstack.getData(), d0 + (double) b0 * 0.3D, d1 - 0.3D, d2 + (double) b1 * 0.3D);
+                    world.triggerEffect(1002, i, j, k, 0);
+                } else if (itemstack.id == Item.FIREBALL.id) {
+                    EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0 + (double) b0 * 0.3D, d1, d2 + (double) b1 * 0.3D, (double) b0 + random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, (double) b1 + random.nextGaussian() * 0.05D);
+
+                    world.addEntity(entitysmallfireball);
+                    world.triggerEffect(1009, i, j, k, 0);
                 } else {
                     EntityItem entityitem = new EntityItem(world, d0, d1 - 0.3D, d2, itemstack);
                     // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/BlockDoor.java b/src/main/java/net/minecraft/server/BlockDoor.java
index a780955230..8ce6fc8d4a 100644
--- a/src/main/java/net/minecraft/server/BlockDoor.java
+++ b/src/main/java/net/minecraft/server/BlockDoor.java
@@ -19,33 +19,16 @@ public class BlockDoor extends Block {
         this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
     }
 
-    public int a(int i, int j) {
-        if (i != 0 && i != 1) {
-            int k = this.e(j);
-
-            if ((k == 0 || k == 2) ^ i <= 3) {
-                return this.textureId;
-            } else {
-                int l = k / 2 + (i & 1 ^ k);
-
-                l += (j & 4) / 4;
-                int i1 = this.textureId - (j & 8) * 2;
-
-                if ((l & 1) != 0) {
-                    i1 = -i1;
-                }
-
-                return i1;
-            }
-        } else {
-            return this.textureId;
-        }
-    }
-
     public boolean a() {
         return false;
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        int l = this.e(iblockaccess, i, j, k);
+
+        return (l & 4) != 0;
+    }
+
     public boolean b() {
         return false;
     }
@@ -60,27 +43,57 @@ public class BlockDoor extends Block {
     }
 
     public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
-        this.d(this.e(iblockaccess.getData(i, j, k)));
+        this.d(this.e(iblockaccess, i, j, k));
     }
 
-    public void d(int i) {
+    public int c(IBlockAccess iblockaccess, int i, int j, int k) {
+        return this.e(iblockaccess, i, j, k) & 3;
+    }
+
+    public boolean d(IBlockAccess iblockaccess, int i, int j, int k) {
+        return (this.e(iblockaccess, i, j, k) & 4) != 0;
+    }
+
+    private void d(int i) {
         float f = 0.1875F;
 
         this.a(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F);
-        if (i == 0) {
-            this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
-        }
+        int j = i & 3;
+        boolean flag = (i & 4) != 0;
+        boolean flag1 = (i & 16) != 0;
 
-        if (i == 1) {
-            this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
-        }
-
-        if (i == 2) {
-            this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
-        }
-
-        if (i == 3) {
-            this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
+        if (j == 0) {
+            if (!flag) {
+                this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
+            } else if (!flag1) {
+                this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
+            } else {
+                this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
+            }
+        } else if (j == 1) {
+            if (!flag) {
+                this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
+            } else if (!flag1) {
+                this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+            } else {
+                this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
+            }
+        } else if (j == 2) {
+            if (!flag) {
+                this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+            } else if (!flag1) {
+                this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
+            } else {
+                this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f);
+            }
+        } else if (j == 3) {
+            if (!flag) {
+                this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F);
+            } else if (!flag1) {
+                this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F);
+            } else {
+                this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+            }
         }
     }
 
@@ -92,46 +105,40 @@ public class BlockDoor extends Block {
         if (this.material == Material.ORE) {
             return true;
         } else {
-            int l = world.getData(i, j, k);
+            int l = this.e((IBlockAccess) world, i, j, k);
+            int i1 = l & 7;
 
+            i1 ^= 4;
             if ((l & 8) != 0) {
-                if (world.getTypeId(i, j - 1, k) == this.id) {
-                    this.interact(world, i, j - 1, k, entityhuman);
-                }
-
-                return true;
-            } else {
-                if (world.getTypeId(i, j + 1, k) == this.id) {
-                    world.setData(i, j + 1, k, (l ^ 4) + 8);
-                }
-
-                world.setData(i, j, k, l ^ 4);
+                world.setData(i, j - 1, k, i1);
                 world.b(i, j - 1, k, i, j, k);
-                world.a(entityhuman, 1003, i, j, k, 0);
-                return true;
+            } else {
+                world.setData(i, j, k, i1);
+                world.b(i, j, k, i, j, k);
             }
+
+            world.a(entityhuman, 1003, i, j, k, 0);
+            return true;
         }
     }
 
     public void setDoor(World world, int i, int j, int k, boolean flag) {
-        int l = world.getData(i, j, k);
+        int l = this.e((IBlockAccess) world, i, j, k);
+        boolean flag1 = (l & 4) != 0;
 
-        if ((l & 8) != 0) {
-            if (world.getTypeId(i, j - 1, k) == this.id) {
-                this.setDoor(world, i, j - 1, k, flag);
-            }
-        } else {
-            boolean flag1 = (world.getData(i, j, k) & 4) > 0;
+        if (flag1 != flag) {
+            int i1 = l & 7;
 
-            if (flag1 != flag) {
-                if (world.getTypeId(i, j + 1, k) == this.id) {
-                    world.setData(i, j + 1, k, (l ^ 4) + 8);
-                }
-
-                world.setData(i, j, k, l ^ 4);
+            i1 ^= 4;
+            if ((l & 8) != 0) {
+                world.setData(i, j - 1, k, i1);
                 world.b(i, j - 1, k, i, j, k);
-                world.a((EntityHuman) null, 1003, i, j, k, 0);
+            } else {
+                world.setData(i, j, k, i1);
+                world.b(i, j, k, i, j, k);
             }
+
+            world.a((EntityHuman) null, 1003, i, j, k, 0);
         }
     }
 
@@ -196,19 +203,31 @@ public class BlockDoor extends Block {
         return super.a(world, i, j, k, vec3d, vec3d1);
     }
 
-    public int e(int i) {
-        return (i & 4) == 0 ? i - 1 & 3 : i & 3;
-    }
-
     public boolean canPlace(World world, int i, int j, int k) {
-        return j >= world.height - 1 ? false : world.e(i, j - 1, k) && super.canPlace(world, i, j, k) && super.canPlace(world, i, j + 1, k);
-    }
-
-    public static boolean f(int i) {
-        return (i & 4) != 0;
+        return j >= 255 ? false : world.e(i, j - 1, k) && super.canPlace(world, i, j, k) && super.canPlace(world, i, j + 1, k);
     }
 
     public int g() {
         return 1;
     }
+
+    public int e(IBlockAccess iblockaccess, int i, int j, int k) {
+        int l = iblockaccess.getData(i, j, k);
+        boolean flag = (l & 8) != 0;
+        int i1;
+        int j1;
+
+        if (flag) {
+            i1 = iblockaccess.getData(i, j - 1, k);
+            j1 = l;
+        } else {
+            i1 = l;
+            j1 = iblockaccess.getData(i, j + 1, k);
+        }
+
+        boolean flag1 = (j1 & 1) != 0;
+        int k1 = i1 & 7 | (flag ? 8 : 0) | (flag1 ? 16 : 0);
+
+        return k1;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/BlockFire.java b/src/main/java/net/minecraft/server/BlockFire.java
index 3c5e15070d..f620e60dac 100644
--- a/src/main/java/net/minecraft/server/BlockFire.java
+++ b/src/main/java/net/minecraft/server/BlockFire.java
@@ -60,7 +60,7 @@ public class BlockFire extends Block {
     }
 
     public int d() {
-        return 40;
+        return 30;
     }
 
     public void a(World world, int i, int j, int k, Random random) {
@@ -74,7 +74,7 @@ public class BlockFire extends Block {
             fireExtinguished(world, i, j, k);   // CraftBukkit - invalid place location
         }
 
-        if (!flag && world.w() && (world.v(i, j, k) || world.v(i - 1, j, k) || world.v(i + 1, j, k) || world.v(i, j, k - 1) || world.v(i, j, k + 1))) {
+        if (!flag && world.x() && (world.y(i, j, k) || world.y(i - 1, j, k) || world.y(i + 1, j, k) || world.y(i, j, k - 1) || world.y(i, j, k + 1))) {
             fireExtinguished(world, i, j, k);   // CraftBukkit - extinguished by rain
         } else {
             int l = world.getData(i, j, k);
@@ -83,20 +83,27 @@ public class BlockFire extends Block {
                 world.setRawData(i, j, k, l + random.nextInt(3) / 2);
             }
 
-            world.c(i, j, k, this.id, this.d());
+            world.c(i, j, k, this.id, this.d() + random.nextInt(10));
             if (!flag && !this.g(world, i, j, k)) {
                 if (!world.e(i, j - 1, k) || l > 3) {
                     fireExtinguished(world, i, j, k);   // CraftBukkit - burn out
                 }
-            } else if (!flag && !this.b(world, i, j - 1, k) && l == 15 && random.nextInt(4) == 0) {
+            } else if (!flag && !this.c(world, i, j - 1, k) && l == 15 && random.nextInt(4) == 0) {
                 fireExtinguished(world, i, j, k);   // CraftBukkit - burn out
             } else {
-                this.a(world, i + 1, j, k, 300, random, l);
-                this.a(world, i - 1, j, k, 300, random, l);
-                this.a(world, i, j - 1, k, 250, random, l);
-                this.a(world, i, j + 1, k, 250, random, l);
-                this.a(world, i, j, k - 1, 300, random, l);
-                this.a(world, i, j, k + 1, 300, random, l);
+                boolean flag1 = world.z(i, j, k);
+                byte b0 = 0;
+
+                if (flag1) {
+                    b0 = -50;
+                }
+
+                this.a(world, i + 1, j, k, 300 + b0, random, l);
+                this.a(world, i - 1, j, k, 300 + b0, random, l);
+                this.a(world, i, j - 1, k, 250 + b0, random, l);
+                this.a(world, i, j + 1, k, 250 + b0, random, l);
+                this.a(world, i, j, k - 1, 300 + b0, random, l);
+                this.a(world, i, j, k + 1, 300 + b0, random, l);
 
                 // CraftBukkit start - Call to stop spread of fire.
                 org.bukkit.Server server = world.getServer();
@@ -121,7 +128,11 @@ public class BlockFire extends Block {
                                 if (i2 > 0) {
                                     int j2 = (i2 + 40) / (l + 30);
 
-                                    if (j2 > 0 && random.nextInt(l1) <= j2 && (!world.w() || !world.v(i1, k1, j1)) && !world.v(i1 - 1, k1, k) && !world.v(i1 + 1, k1, j1) && !world.v(i1, k1, j1 - 1) && !world.v(i1, k1, j1 + 1)) {
+                                    if (flag1) {
+                                        j2 /= 2;
+                                    }
+
+                                    if (j2 > 0 && random.nextInt(l1) <= j2 && (!world.x() || !world.y(i1, k1, j1)) && !world.y(i1 - 1, k1, k) && !world.y(i1 + 1, k1, j1) && !world.y(i1, k1, j1 - 1) && !world.y(i1, k1, j1 + 1)) {
                                         int k2 = l + random.nextInt(5) / 4;
 
                                         if (k2 > 15) {
@@ -176,7 +187,7 @@ public class BlockFire extends Block {
             }
             // CraftBukkit end
 
-            if (random.nextInt(i1 + 10) < 5 && !world.v(i, j, k)) {
+            if (random.nextInt(i1 + 10) < 5 && !world.y(i, j, k)) {
                 int k1 = i1 + random.nextInt(5) / 4;
 
                 if (k1 > 15) {
@@ -195,7 +206,7 @@ public class BlockFire extends Block {
     }
 
     private boolean g(World world, int i, int j, int k) {
-        return this.b(world, i + 1, j, k) ? true : (this.b(world, i - 1, j, k) ? true : (this.b(world, i, j - 1, k) ? true : (this.b(world, i, j + 1, k) ? true : (this.b(world, i, j, k - 1) ? true : this.b(world, i, j, k + 1)))));
+        return this.c(world, i + 1, j, k) ? true : (this.c(world, i - 1, j, k) ? true : (this.c(world, i, j - 1, k) ? true : (this.c(world, i, j + 1, k) ? true : (this.c(world, i, j, k - 1) ? true : this.c(world, i, j, k + 1)))));
     }
 
     private int h(World world, int i, int j, int k) {
@@ -215,11 +226,11 @@ public class BlockFire extends Block {
         }
     }
 
-    public boolean x_() {
+    public boolean F_() {
         return false;
     }
 
-    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+    public boolean c(IBlockAccess iblockaccess, int i, int j, int k) {
         return this.a[iblockaccess.getTypeId(i, j, k)] > 0;
     }
 
@@ -244,7 +255,7 @@ public class BlockFire extends Block {
             if (!world.e(i, j - 1, k) && !this.g(world, i, j, k)) {
                 fireExtinguished(world, i, j, k);   // CraftBukkit - fuel block broke
             } else {
-                world.c(i, j, k, this.id, this.d());
+                world.c(i, j, k, this.id, this.d() + world.random.nextInt(10));
             }
         }
     }
diff --git a/src/main/java/net/minecraft/server/BlockFlowing.java b/src/main/java/net/minecraft/server/BlockFlowing.java
index e1e0c5d7dc..347733f2b6 100644
--- a/src/main/java/net/minecraft/server/BlockFlowing.java
+++ b/src/main/java/net/minecraft/server/BlockFlowing.java
@@ -25,6 +25,10 @@ public class BlockFlowing extends BlockFluids {
         world.notify(i, j, k);
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        return this.material != Material.LAVA;
+    }
+
     public void a(World world, int i, int j, int k, Random random) {
         // CraftBukkit start
         org.bukkit.World bworld = world.getWorld();
@@ -35,7 +39,7 @@ public class BlockFlowing extends BlockFluids {
         int l = this.g(world, i, j, k);
         byte b0 = 1;
 
-        if (this.material == Material.LAVA && !world.worldProvider.e) {
+        if (this.material == Material.LAVA && !world.worldProvider.d) {
             b0 = 2;
         }
 
diff --git a/src/main/java/net/minecraft/server/BlockFurnace.java b/src/main/java/net/minecraft/server/BlockFurnace.java
index 2a28360119..9d9fde7c47 100644
--- a/src/main/java/net/minecraft/server/BlockFurnace.java
+++ b/src/main/java/net/minecraft/server/BlockFurnace.java
@@ -31,19 +31,19 @@ public class BlockFurnace extends BlockContainer {
             int k1 = world.getTypeId(i + 1, j, k);
             byte b0 = 3;
 
-            if (Block.o[l] && !Block.o[i1]) {
+            if (Block.n[l] && !Block.n[i1]) {
                 b0 = 3;
             }
 
-            if (Block.o[i1] && !Block.o[l]) {
+            if (Block.n[i1] && !Block.n[l]) {
                 b0 = 2;
             }
 
-            if (Block.o[j1] && !Block.o[k1]) {
+            if (Block.n[j1] && !Block.n[k1]) {
                 b0 = 5;
             }
 
-            if (Block.o[k1] && !Block.o[j1]) {
+            if (Block.n[k1] && !Block.n[j1]) {  
                 b0 = 4;
             }
 
diff --git a/src/main/java/net/minecraft/server/BlockLeaves.java b/src/main/java/net/minecraft/server/BlockLeaves.java
index 1538397ae4..1f2590b67a 100644
--- a/src/main/java/net/minecraft/server/BlockLeaves.java
+++ b/src/main/java/net/minecraft/server/BlockLeaves.java
@@ -139,14 +139,27 @@ public class BlockLeaves extends BlockTransparant {
     }
 
     public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
-        super.dropNaturally(world, i, j, k, l, f, i1);
-        if (!world.isStatic && (l & 3) == 0 && world.random.nextInt(200) == 0) {
-            this.a(world, i, j, k, new ItemStack(Item.APPLE, 1, 0));
+        if (!world.isStatic) {
+            byte b0 = 20;
+
+            if ((l & 3) == 3) {
+                b0 = 40;
+            }
+
+            if (world.random.nextInt(b0) == 0) {
+                int j1 = this.getDropType(l, world.random, i1);
+
+                this.a(world, i, j, k, new ItemStack(j1, 1, this.getDropData(l)));
+            }
+
+            if ((l & 3) == 0 && world.random.nextInt(200) == 0) {
+                this.a(world, i, j, k, new ItemStack(Item.APPLE, 1, 0));
+            }
         }
     }
 
     public void a(World world, EntityHuman entityhuman, int i, int j, int k, int l) {
-        if (!world.isStatic && entityhuman.Q() != null && entityhuman.Q().id == Item.SHEARS.id) {
+        if (!world.isStatic && entityhuman.T() != null && entityhuman.T().id == Item.SHEARS.id) {
             entityhuman.a(StatisticList.C[this.id], 1);
             this.a(world, i, j, k, new ItemStack(Block.LEAVES.id, 1, l & 3));
         } else {
@@ -163,7 +176,7 @@ public class BlockLeaves extends BlockTransparant {
     }
 
     public int a(int i, int j) {
-        return (j & 3) == 1 ? this.textureId + 80 : this.textureId;
+        return (j & 3) == 1 ? this.textureId + 80 : ((j & 3) == 3 ? this.textureId + 144 : this.textureId);
     }
 
     public void b(World world, int i, int j, int k, Entity entity) {
diff --git a/src/main/java/net/minecraft/server/BlockMinecartTrack.java b/src/main/java/net/minecraft/server/BlockMinecartTrack.java
deleted file mode 100644
index 335d6a8c2d..0000000000
--- a/src/main/java/net/minecraft/server/BlockMinecartTrack.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package net.minecraft.server;
-
-import java.util.Random;
-
-public class BlockMinecartTrack extends Block {
-
-    private final boolean a;
-
-    public static final boolean g(World world, int i, int j, int k) {
-        int l = world.getTypeId(i, j, k);
-
-        return l == Block.RAILS.id || l == Block.GOLDEN_RAIL.id || l == Block.DETECTOR_RAIL.id;
-    }
-
-    public static final boolean d(int i) {
-        return i == Block.RAILS.id || i == Block.GOLDEN_RAIL.id || i == Block.DETECTOR_RAIL.id;
-    }
-
-    protected BlockMinecartTrack(int i, int j, boolean flag) {
-        super(i, j, Material.ORIENTABLE);
-        this.a = flag;
-        this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
-    }
-
-    public boolean h() {
-        return this.a;
-    }
-
-    public AxisAlignedBB e(World world, int i, int j, int k) {
-        return null;
-    }
-
-    public boolean a() {
-        return false;
-    }
-
-    public MovingObjectPosition a(World world, int i, int j, int k, Vec3D vec3d, Vec3D vec3d1) {
-        this.updateShape(world, i, j, k);
-        return super.a(world, i, j, k, vec3d, vec3d1);
-    }
-
-    public void updateShape(IBlockAccess iblockaccess, int i, int j, int k) {
-        int l = iblockaccess.getData(i, j, k);
-
-        if (l >= 2 && l <= 5) {
-            this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F);
-        } else {
-            this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F);
-        }
-    }
-
-    public int a(int i, int j) {
-        if (this.a) {
-            if (this.id == Block.GOLDEN_RAIL.id && (j & 8) == 0) {
-                return this.textureId - 16;
-            }
-        } else if (j >= 6) {
-            return this.textureId - 16;
-        }
-
-        return this.textureId;
-    }
-
-    public boolean b() {
-        return false;
-    }
-
-    public int c() {
-        return 9;
-    }
-
-    public int a(Random random) {
-        return 1;
-    }
-
-    public boolean canPlace(World world, int i, int j, int k) {
-        return world.e(i, j - 1, k);
-    }
-
-    public void onPlace(World world, int i, int j, int k) {
-        if (!world.isStatic) {
-            this.a(world, i, j, k, true);
-            if (this.id == Block.GOLDEN_RAIL.id) {
-                //this.doPhysics(world, i, j, k, this.id); // CraftBukkit - Fix dupe with pistons
-            }
-        }
-    }
-
-    public void doPhysics(World world, int i, int j, int k, int l) {
-        if (!world.isStatic) {
-            int i1 = world.getData(i, j, k);
-            int j1 = i1;
-
-            if (this.a) {
-                j1 = i1 & 7;
-            }
-
-            boolean flag = false;
-
-            if (!world.e(i, j - 1, k)) {
-                flag = true;
-            }
-
-            if (j1 == 2 && !world.e(i + 1, j, k)) {
-                flag = true;
-            }
-
-            if (j1 == 3 && !world.e(i - 1, j, k)) {
-                flag = true;
-            }
-
-            if (j1 == 4 && !world.e(i, j, k - 1)) {
-                flag = true;
-            }
-
-            if (j1 == 5 && !world.e(i, j, k + 1)) {
-                flag = true;
-            }
-
-            if (flag) {
-                this.b(world, i, j, k, world.getData(i, j, k), 0);
-                world.setTypeId(i, j, k, 0);
-            } else if (this.id == Block.GOLDEN_RAIL.id) {
-                boolean flag1 = world.isBlockIndirectlyPowered(i, j, k) || world.isBlockIndirectlyPowered(i, j + 1, k);
-
-                flag1 = flag1 || this.a(world, i, j, k, i1, true, 0) || this.a(world, i, j, k, i1, false, 0);
-                boolean flag2 = false;
-
-                if (flag1 && (i1 & 8) == 0) {
-                    world.setData(i, j, k, j1 | 8);
-                    flag2 = true;
-                } else if (!flag1 && (i1 & 8) != 0) {
-                    world.setData(i, j, k, j1);
-                    flag2 = true;
-                }
-
-                if (flag2) {
-                    world.applyPhysics(i, j - 1, k, this.id);
-                    if (j1 == 2 || j1 == 3 || j1 == 4 || j1 == 5) {
-                        world.applyPhysics(i, j + 1, k, this.id);
-                    }
-                }
-            } else if (l > 0 && Block.byId[l].isPowerSource() && !this.a && MinecartTrackLogic.a(new MinecartTrackLogic(this, world, i, j, k)) == 3) {
-                this.a(world, i, j, k, false);
-            }
-        }
-    }
-
-    private void a(World world, int i, int j, int k, boolean flag) {
-        if (!world.isStatic) {
-            (new MinecartTrackLogic(this, world, i, j, k)).a(world.isBlockIndirectlyPowered(i, j, k), flag);
-        }
-    }
-
-    private boolean a(World world, int i, int j, int k, int l, boolean flag, int i1) {
-        if (i1 >= 8) {
-            return false;
-        } else {
-            int j1 = l & 7;
-            boolean flag1 = true;
-
-            switch (j1) {
-            case 0:
-                if (flag) {
-                    ++k;
-                } else {
-                    --k;
-                }
-                break;
-
-            case 1:
-                if (flag) {
-                    --i;
-                } else {
-                    ++i;
-                }
-                break;
-
-            case 2:
-                if (flag) {
-                    --i;
-                } else {
-                    ++i;
-                    ++j;
-                    flag1 = false;
-                }
-
-                j1 = 1;
-                break;
-
-            case 3:
-                if (flag) {
-                    --i;
-                    ++j;
-                    flag1 = false;
-                } else {
-                    ++i;
-                }
-
-                j1 = 1;
-                break;
-
-            case 4:
-                if (flag) {
-                    ++k;
-                } else {
-                    --k;
-                    ++j;
-                    flag1 = false;
-                }
-
-                j1 = 0;
-                break;
-
-            case 5:
-                if (flag) {
-                    ++k;
-                    ++j;
-                    flag1 = false;
-                } else {
-                    --k;
-                }
-
-                j1 = 0;
-            }
-
-            return this.a(world, i, j, k, flag, i1, j1) ? true : flag1 && this.a(world, i, j - 1, k, flag, i1, j1);
-        }
-    }
-
-    private boolean a(World world, int i, int j, int k, boolean flag, int l, int i1) {
-        int j1 = world.getTypeId(i, j, k);
-
-        if (j1 == Block.GOLDEN_RAIL.id) {
-            int k1 = world.getData(i, j, k);
-            int l1 = k1 & 7;
-
-            if (i1 == 1 && (l1 == 0 || l1 == 4 || l1 == 5)) {
-                return false;
-            }
-
-            if (i1 == 0 && (l1 == 1 || l1 == 2 || l1 == 3)) {
-                return false;
-            }
-
-            if ((k1 & 8) != 0) {
-                if (!world.isBlockIndirectlyPowered(i, j, k) && !world.isBlockIndirectlyPowered(i, j + 1, k)) {
-                    return this.a(world, i, j, k, k1, flag, l + 1);
-                }
-
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public int g() {
-        return 0;
-    }
-
-    static boolean a(BlockMinecartTrack blockminecarttrack) {
-        return blockminecarttrack.a;
-    }
-}
diff --git a/src/main/java/net/minecraft/server/BlockMushroom.java b/src/main/java/net/minecraft/server/BlockMushroom.java
index cdf09b46bf..8a90307068 100644
--- a/src/main/java/net/minecraft/server/BlockMushroom.java
+++ b/src/main/java/net/minecraft/server/BlockMushroom.java
@@ -77,14 +77,14 @@ public class BlockMushroom extends BlockFlower {
     }
 
     protected boolean d(int i) {
-        return Block.o[i];
+        return Block.n[i];
     }
 
     public boolean f(World world, int i, int j, int k) {
-        if (j >= 0 && j < world.height) {
+        if (j >= 0 && j < 256) {
             int l = world.getTypeId(i, j - 1, k);
 
-            return l == Block.MYCEL.id || world.k(i, j, k) < 13 && this.d(l);
+            return l == Block.MYCEL.id || world.m(i, j, k) < 13 && this.d(l);
         } else {
             return false;
         }
diff --git a/src/main/java/net/minecraft/server/BlockNetherWart.java b/src/main/java/net/minecraft/server/BlockNetherWart.java
index c6e635ab31..8230de9846 100644
--- a/src/main/java/net/minecraft/server/BlockNetherWart.java
+++ b/src/main/java/net/minecraft/server/BlockNetherWart.java
@@ -16,18 +16,18 @@ public class BlockNetherWart extends BlockFlower {
         return i == Block.SOUL_SAND.id;
     }
 
+    public boolean f(World world, int i, int j, int k) {
+        return this.d(world.getTypeId(i, j - 1, k));
+    }
+
     public void a(World world, int i, int j, int k, Random random) {
         int l = world.getData(i, j, k);
 
         if (l < 3) {
-            WorldChunkManager worldchunkmanager = world.getWorldChunkManager();
+            BiomeBase biomebase = world.getBiome(i, k);
 
-            if (worldchunkmanager != null) {
-                BiomeBase biomebase = worldchunkmanager.getBiome(i, k);
-
-                if (biomebase instanceof BiomeHell && random.nextInt(15) == 0) {
-                    org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this.id, ++l); // CraftBukkit
-                }
+            if (biomebase instanceof BiomeHell && random.nextInt(10) == 0) {
+                org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this.id, ++l); // CraftBukkit
             }
         }
 
diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java
index 0e35a7bb1c..39a880ded4 100644
--- a/src/main/java/net/minecraft/server/BlockPiston.java
+++ b/src/main/java/net/minecraft/server/BlockPiston.java
@@ -139,7 +139,7 @@ public class BlockPiston extends Block {
                         if (tileentitypiston.f() == i1 && tileentitypiston.e()) {
                             tileentitypiston.g();
                             i2 = tileentitypiston.c();
-                            j2 = tileentitypiston.j();
+                            j2 = tileentitypiston.k();
                             flag = true;
                         }
                     }
@@ -213,6 +213,11 @@ public class BlockPiston extends Block {
         super.a(world, i, j, k, axisalignedbb, arraylist);
     }
 
+    public AxisAlignedBB e(World world, int i, int j, int k) {
+        this.updateShape(world, i, j, k);
+        return super.e(world, i, j, k);
+    }
+
     public boolean b() {
         return false;
     }
@@ -277,7 +282,7 @@ public class BlockPiston extends Block {
 
         while (true) {
             if (l1 < 13) {
-                if (j1 <= 0 || j1 >= world.height - 1) {
+                if (j1 <= 0 || j1 >= 255) {
                     return -1; // CraftBukkit
                 }
 
@@ -316,7 +321,7 @@ public class BlockPiston extends Block {
             int i2;
 
             if (l1 < 13) {
-                if (j1 <= 0 || j1 >= world.height - 1) {
+                if (j1 <= 0 || j1 >= 255) {
                     return false;
                 }
 
diff --git a/src/main/java/net/minecraft/server/BlockPortal.java b/src/main/java/net/minecraft/server/BlockPortal.java
index 7e8717d715..f14537b494 100644
--- a/src/main/java/net/minecraft/server/BlockPortal.java
+++ b/src/main/java/net/minecraft/server/BlockPortal.java
@@ -166,7 +166,7 @@ public class BlockPortal extends BlockHalfTransparant {
             world.getServer().getPluginManager().callEvent(event);
             // CraftBukkit end
 
-            entity.Y();
+            entity.ac();
         }
     }
 }
diff --git a/src/main/java/net/minecraft/server/BlockPressurePlate.java b/src/main/java/net/minecraft/server/BlockPressurePlate.java
index 9bbb2d11ec..9f32d09158 100644
--- a/src/main/java/net/minecraft/server/BlockPressurePlate.java
+++ b/src/main/java/net/minecraft/server/BlockPressurePlate.java
@@ -38,6 +38,10 @@ public class BlockPressurePlate extends Block {
         return false;
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        return true;
+    }
+
     public boolean canPlace(World world, int i, int j, int k) {
         return world.e(i, j - 1, k) || world.getTypeId(i, j - 1, k) == Block.FENCE.id;
     }
@@ -80,7 +84,7 @@ public class BlockPressurePlate extends Block {
         List list = null;
 
         if (this.a == EnumMobType.EVERYTHING) {
-            list = world.getEntities(null, AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) j + 0.25D, (double) ((float) (k + 1) - f)));
+            list = world.getEntities((Entity) null, AxisAlignedBB.b((double) ((float) i + f), (double) j, (double) ((float) k + f), (double) ((float) (i + 1) - f), (double) j + 0.25D, (double) ((float) (k + 1) - f)));
         }
 
         if (this.a == EnumMobType.MOBS) {
diff --git a/src/main/java/net/minecraft/server/BlockPumpkin.java b/src/main/java/net/minecraft/server/BlockPumpkin.java
index a702c5e4e9..dcc86931c2 100644
--- a/src/main/java/net/minecraft/server/BlockPumpkin.java
+++ b/src/main/java/net/minecraft/server/BlockPumpkin.java
@@ -2,7 +2,7 @@ package net.minecraft.server;
 
 import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
 
-public class BlockPumpkin extends Block {
+public class BlockPumpkin extends BlockDirectional {
 
     private boolean a;
 
@@ -38,18 +38,58 @@ public class BlockPumpkin extends Block {
         if (world.suppressPhysics) return; // CraftBukkit
         if (world.getTypeId(i, j - 1, k) == Block.SNOW_BLOCK.id && world.getTypeId(i, j - 2, k) == Block.SNOW_BLOCK.id) {
             if (!world.isStatic && world.getServer().getServer().spawnAnimals) { // CraftBukkit - make snowmen obey spawning rules
-                world.setTypeId(i, j, k, 0);
-                world.setTypeId(i, j - 1, k, 0);
-                world.setTypeId(i, j - 2, k, 0);
+                world.setRawTypeId(i, j, k, 0);
+                world.setRawTypeId(i, j - 1, k, 0);
+                world.setRawTypeId(i, j - 2, k, 0);
                 EntitySnowman entitysnowman = new EntitySnowman(world);
 
                 entitysnowman.setPositionRotation((double) i + 0.5D, (double) j - 1.95D, (double) k + 0.5D, 0.0F, 0.0F);
                 world.addEntity(entitysnowman, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_SNOWMAN); // CraftBukkit
+                world.update(i, j, k, 0);
+                world.update(i, j - 1, k, 0);
+                world.update(i, j - 2, k, 0);
             }
 
             for (int l = 0; l < 120; ++l) {
                 world.a("snowshovel", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 2.5D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
             }
+        } else if (world.getTypeId(i, j - 1, k) == Block.IRON_BLOCK.id && world.getTypeId(i, j - 2, k) == Block.IRON_BLOCK.id) {
+            boolean flag = world.getTypeId(i - 1, j - 1, k) == Block.IRON_BLOCK.id && world.getTypeId(i + 1, j - 1, k) == Block.IRON_BLOCK.id;
+            boolean flag1 = world.getTypeId(i, j - 1, k - 1) == Block.IRON_BLOCK.id && world.getTypeId(i, j - 1, k + 1) == Block.IRON_BLOCK.id;
+
+            if (flag || flag1) {
+                world.setRawTypeId(i, j, k, 0);
+                world.setRawTypeId(i, j - 1, k, 0);
+                world.setRawTypeId(i, j - 2, k, 0);
+                if (flag) {
+                    world.setRawTypeId(i - 1, j - 1, k, 0);
+                    world.setRawTypeId(i + 1, j - 1, k, 0);
+                } else {
+                    world.setRawTypeId(i, j - 1, k - 1, 0);
+                    world.setRawTypeId(i, j - 1, k + 1, 0);
+                }
+
+                EntityIronGolem entityirongolem = new EntityIronGolem(world);
+
+                entityirongolem.b(true);
+                entityirongolem.setPositionRotation((double) i + 0.5D, (double) j - 1.95D, (double) k + 0.5D, 0.0F, 0.0F);
+                world.addEntity(entityirongolem);
+
+                for (int i1 = 0; i1 < 120; ++i1) {
+                    world.a("snowballpoof", (double) i + world.random.nextDouble(), (double) (j - 2) + world.random.nextDouble() * 3.9D, (double) k + world.random.nextDouble(), 0.0D, 0.0D, 0.0D);
+                }
+
+                world.update(i, j, k, 0);
+                world.update(i, j - 1, k, 0);
+                world.update(i, j - 2, k, 0);
+                if (flag) {
+                    world.update(i - 1, j - 1, k, 0);
+                    world.update(i + 1, j - 1, k, 0);
+                } else {
+                    world.update(i, j - 1, k - 1, 0);
+                    world.update(i, j - 1, k + 1, 0);
+                }
+            }
         }
     }
 
diff --git a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
index e9986db99b..21c7593eb5 100644
--- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
+++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
@@ -91,7 +91,7 @@ public class BlockRedstoneTorch extends BlockTorch {
     public void a(World world, int i, int j, int k, Random random) {
         boolean flag = this.g(world, i, j, k);
 
-        while (b.size() > 0 && world.getTime() - ((RedstoneUpdateInfo) b.get(0)).d > 100L) {
+        while (b.size() > 0 && world.getTime() - ((RedstoneUpdateInfo) b.get(0)).d > 60L) {
             b.remove(0);
         }
 
diff --git a/src/main/java/net/minecraft/server/BlockRedstoneWire.java b/src/main/java/net/minecraft/server/BlockRedstoneWire.java
index b79743e41e..5c38f7806f 100644
--- a/src/main/java/net/minecraft/server/BlockRedstoneWire.java
+++ b/src/main/java/net/minecraft/server/BlockRedstoneWire.java
@@ -38,7 +38,7 @@ public class BlockRedstoneWire extends Block {
     }
 
     public boolean canPlace(World world, int i, int j, int k) {
-        return world.e(i, j - 1, k);
+        return world.e(i, j - 1, k) || world.getTypeId(i, j - 1, k) == Block.GLOWSTONE.id;
     }
 
     private void g(World world, int i, int j, int k) {
diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java
index 0040474b2d..88489ed3d5 100644
--- a/src/main/java/net/minecraft/server/BlockSapling.java
+++ b/src/main/java/net/minecraft/server/BlockSapling.java
@@ -37,7 +37,7 @@ public class BlockSapling extends BlockFlower {
 
     public int a(int i, int j) {
         j &= 3;
-        return j == 1 ? 63 : (j == 2 ? 79 : super.a(i, j));
+        return j == 1 ? 63 : (j == 2 ? 79 : (j == 3 ? 30 : super.a(i, j)));
     }
 
     // CraftBukkit - added bonemeal, player and itemstack
diff --git a/src/main/java/net/minecraft/server/BlockSign.java b/src/main/java/net/minecraft/server/BlockSign.java
index 453cfafd48..2d57b776e4 100644
--- a/src/main/java/net/minecraft/server/BlockSign.java
+++ b/src/main/java/net/minecraft/server/BlockSign.java
@@ -60,6 +60,10 @@ public class BlockSign extends BlockContainer {
         return false;
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        return true;
+    }
+
     public boolean a() {
         return false;
     }
diff --git a/src/main/java/net/minecraft/server/BlockSoil.java b/src/main/java/net/minecraft/server/BlockSoil.java
index dc38e1af59..591dd773b8 100644
--- a/src/main/java/net/minecraft/server/BlockSoil.java
+++ b/src/main/java/net/minecraft/server/BlockSoil.java
@@ -14,7 +14,7 @@ public class BlockSoil extends Block {
         this.textureId = 87;
         this.a(true);
         this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F);
-        this.g(255);
+        this.f(255);
     }
 
     public AxisAlignedBB e(World world, int i, int j, int k) {
@@ -34,7 +34,7 @@ public class BlockSoil extends Block {
     }
 
     public void a(World world, int i, int j, int k, Random random) {
-        if (!this.h(world, i, j, k) && !world.v(i, j + 1, k)) {
+        if (!this.h(world, i, j, k) && !world.y(i, j + 1, k)) {
             int l = world.getData(i, j, k);
 
             if (l > 0) {
diff --git a/src/main/java/net/minecraft/server/BlockStationary.java b/src/main/java/net/minecraft/server/BlockStationary.java
index 1b091e700b..d4f276c90c 100644
--- a/src/main/java/net/minecraft/server/BlockStationary.java
+++ b/src/main/java/net/minecraft/server/BlockStationary.java
@@ -14,6 +14,10 @@ public class BlockStationary extends BlockFluids {
         }
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        return this.material != Material.LAVA;
+    }
+
     public void doPhysics(World world, int i, int j, int k, int l) {
         super.doPhysics(world, i, j, k, l);
         if (world.getTypeId(i, j, k) == this.id) {
@@ -35,17 +39,19 @@ public class BlockStationary extends BlockFluids {
         if (this.material == Material.LAVA) {
             int l = random.nextInt(3);
 
+            int i1;
+            int j1;
+
             // CraftBukkit start - prevent lava putting something on fire.
             org.bukkit.World bworld = world.getWorld();
             BlockIgniteEvent.IgniteCause igniteCause = BlockIgniteEvent.IgniteCause.LAVA;
             // CraftBukkit end
 
-            for (int i1 = 0; i1 < l; ++i1) {
+            for (i1 = 0; i1 < l; ++i1) {
                 i += random.nextInt(3) - 1;
                 ++j;
                 k += random.nextInt(3) - 1;
-                int j1 = world.getTypeId(i, j, k);
-
+                j1 = world.getTypeId(i, j, k);
                 if (j1 == 0) {
                     if (this.j(world, i - 1, j, k) || this.j(world, i + 1, j, k) || this.j(world, i, j, k - 1) || this.j(world, i, j, k + 1) || this.j(world, i, j - 1, k) || this.j(world, i, j + 1, k)) {
                         // CraftBukkit start - prevent lava putting something on fire.
@@ -68,6 +74,19 @@ public class BlockStationary extends BlockFluids {
                     return;
                 }
             }
+
+            if (l == 0) {
+                i1 = i;
+                j1 = k;
+
+                for (int k1 = 0; k1 < 3; ++k1) {
+                    i = i1 + random.nextInt(3) - 1;
+                    k = j1 + random.nextInt(3) - 1;
+                    if (world.isEmpty(i, j + 1, k) && this.j(world, i, j, k)) {
+                        world.setTypeId(i, j + 1, k, Block.FIRE.id);
+                    }
+                }
+            }
         }
     }
 
diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
index 23b7eb4cbc..f1efb1356e 100644
--- a/src/main/java/net/minecraft/server/BlockTNT.java
+++ b/src/main/java/net/minecraft/server/BlockTNT.java
@@ -52,7 +52,7 @@ public class BlockTNT extends Block {
     }
 
     public void attack(World world, int i, int j, int k, EntityHuman entityhuman) {
-        if (entityhuman.Q() != null && entityhuman.Q().id == Item.FLINT_AND_STEEL.id) {
+        if (entityhuman.T() != null && entityhuman.T().id == Item.FLINT_AND_STEEL.id) {
             world.setRawData(i, j, k, 1);
         }
 
diff --git a/src/main/java/net/minecraft/server/BlockTrapdoor.java b/src/main/java/net/minecraft/server/BlockTrapdoor.java
index 1a8b31a03c..3a27631512 100644
--- a/src/main/java/net/minecraft/server/BlockTrapdoor.java
+++ b/src/main/java/net/minecraft/server/BlockTrapdoor.java
@@ -25,6 +25,10 @@ public class BlockTrapdoor extends Block {
         return false;
     }
 
+    public boolean b(IBlockAccess iblockaccess, int i, int j, int k) {
+        return !e(iblockaccess.getData(i, j, k));
+    }
+
     public int c() {
         return 0;
     }
@@ -115,7 +119,7 @@ public class BlockTrapdoor extends Block {
                 --j1;
             }
 
-            if (!f(world.getTypeId(j1, j, k1))) {
+            if (!h(world.getTypeId(j1, j, k1))) {
                 world.setTypeId(i, j, k, 0);
                 this.b(world, i, j, k, i1, 0);
             }
@@ -189,7 +193,7 @@ public class BlockTrapdoor extends Block {
                 --i;
             }
 
-            return f(world.getTypeId(i, j, k));
+            return h(world.getTypeId(i, j, k));
         }
     }
 
@@ -197,7 +201,7 @@ public class BlockTrapdoor extends Block {
         return (i & 4) != 0;
     }
 
-    private static boolean f(int i) {
+    private static boolean h(int i) {
         if (i <= 0) {
             return false;
         } else {
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 0b813bb1c0..1d775db9cf 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -12,49 +12,50 @@ import org.bukkit.Bukkit; // CraftBukkit
 public class Chunk {
 
     public static boolean a;
-    public byte[] blocks;
-    public int[] c;
-    public boolean[] d;
-    public boolean e;
+    private ChunkSection[] sections;
+    private byte[] q;
+    public int[] b;
+    public boolean[] c;
+    public boolean d;
     public World world;
-    public NibbleArray g;
-    public NibbleArray h;
-    public NibbleArray i;
-    public byte[] heightMap;
-    public int k;
+    public int[] heightMap;
     public final int x;
     public final int z;
-    private boolean v;
+    private boolean r;
     public Map tileEntities;
     public List[] entitySlices;
     public boolean done;
-    public boolean q;
-    public boolean r;
-    public boolean s;
-    public long t;
-    boolean u;
+    public boolean l;
+    public boolean m;
+    public long n;
+    private int s;
+    boolean o;
 
     public Chunk(World world, int i, int j) {
-        this.c = new int[256];
-        this.d = new boolean[256];
-        this.v = false;
+        this.sections = new ChunkSection[16];
+        this.q = new byte[256];
+        this.b = new int[256];
+        this.c = new boolean[256];
+        this.r = false;
         this.tileEntities = new HashMap();
         this.done = false;
-        this.q = false;
-        this.s = false;
-        this.t = 0L;
-        this.u = false;
-        this.entitySlices = new List[world.height / 16];
+        this.l = false;
+        this.m = false;
+        this.n = 0L;
+        this.s = 4096;
+        this.o = false;
+        this.entitySlices = new List[16];
         this.world = world;
         this.x = i;
         this.z = j;
-        this.heightMap = new byte[256];
+        this.heightMap = new int[256];
 
         for (int k = 0; k < this.entitySlices.length; ++k) {
             this.entitySlices[k] = new ArrayList();
         }
 
-        Arrays.fill(this.c, -999);
+        Arrays.fill(this.b, -999);
+        Arrays.fill(this.q, (byte) -1);
 
         // CraftBukkit start
         if (!(this instanceof EmptyChunk)) {
@@ -71,10 +72,25 @@ public class Chunk {
 
     public Chunk(World world, byte[] abyte, int i, int j) {
         this(world, i, j);
-        this.blocks = abyte;
-        this.g = new NibbleArray(abyte.length, world.heightBits);
-        this.h = new NibbleArray(abyte.length, world.heightBits);
-        this.i = new NibbleArray(abyte.length, world.heightBits);
+        int k = abyte.length / 256;
+
+        for (int l = 0; l < 16; ++l) {
+            for (int i1 = 0; i1 < 16; ++i1) {
+                for (int j1 = 0; j1 < k; ++j1) {
+                    byte b0 = abyte[l << 11 | i1 << 7 | j1];
+
+                    if (b0 != 0) {
+                        int k1 = j1 >> 4;
+
+                        if (this.sections[k1] == null) {
+                            this.sections[k1] = new ChunkSection(k1 << 4);
+                        }
+
+                        this.sections[k1].a(l, j1 & 15, i1, b0);
+                    }
+                }
+            }
+        }
     }
 
     public boolean a(int i, int j) {
@@ -82,72 +98,94 @@ public class Chunk {
     }
 
     public int b(int i, int j) {
-        return this.heightMap[j << 4 | i] & 255;
+        return this.heightMap[j << 4 | i];
     }
 
-    public void a() {}
+    public int g() {
+        for (int i = this.sections.length - 1; i >= 0; --i) {
+            if (this.sections[i] != null) {
+                return this.sections[i].c();
+            }
+        }
+
+        return 0;
+    }
+
+    public ChunkSection[] h() {
+        return this.sections;
+    }
 
     public void initLighting() {
-        int i = this.world.height - 1;
+        int i = this.g();
 
         int j;
         int k;
 
         for (j = 0; j < 16; ++j) {
-            for (k = 0; k < 16; ++k) {
-                int l = this.world.height - 1;
+            k = 0;
 
-                int i1;
+            while (k < 16) {
+                this.b[j + (k << 4)] = -999;
+                int l = i + 16 - 1;
 
-                for (i1 = j << this.world.heightBitsPlusFour | k << this.world.heightBits; l > 0 && Block.lightBlock[this.blocks[i1 + l - 1] & 255] == 0; --l) {
-                    ;
-                }
-
-                this.heightMap[k << 4 | j] = (byte) l;
-                if (l < i) {
-                    i = l;
-                }
-
-                if (!this.world.worldProvider.f) {
-                    int j1 = 15;
-                    int k1 = this.world.height - 1;
-
-                    do {
-                        j1 -= Block.lightBlock[this.blocks[i1 + k1] & 255];
-                        if (j1 > 0) {
-                            this.h.a(j, k1, k, j1);
+                while (true) {
+                    if (l > 0) {
+                        if (this.b(j, l - 1, k) == 0) {
+                            --l;
+                            continue;
                         }
 
-                        --k1;
-                    } while (k1 > 0 && j1 > 0);
+                        this.heightMap[k << 4 | j] = l;
+                    }
+
+                    if (!this.world.worldProvider.e) {
+                        l = 15;
+                        int i1 = i + 16 - 1;
+
+                        do {
+                            l -= this.b(j, i1, k);
+                            if (l > 0) {
+                                ChunkSection chunksection = this.sections[i1 >> 4];
+
+                                if (chunksection != null) {
+                                    chunksection.c(j, i1 & 15, k, l);
+                                    this.world.o((this.x << 4) + j, i1, (this.z << 4) + k);
+                                }
+                            }
+
+                            --i1;
+                        } while (i1 > 0 && l > 0);
+                    }
+
+                    ++k;
+                    break;
                 }
             }
         }
 
-        this.k = i;
+        this.l = true;
 
         for (j = 0; j < 16; ++j) {
             for (k = 0; k < 16; ++k) {
-                this.d(j, k);
+                this.e(j, k);
             }
         }
-
-        this.q = true;
     }
 
     public void loadNOP() {}
 
-    private void d(int i, int j) {
-        this.d[i + j * 16] = true;
-        this.v = true;
+    private void e(int i, int j) {
+        this.c[i + j * 16] = true;
+        this.r = true;
     }
 
-    private void k() {
-        if (this.world.areChunksLoaded(this.x * 16 + 8, this.world.height / 2, this.z * 16 + 8, 16)) {
+    private void o() {
+        MethodProfiler.a("recheckGaps");
+        if (this.world.areChunksLoaded(this.x * 16 + 8, 0, this.z * 16 + 8, 16)) {
             for (int i = 0; i < 16; ++i) {
                 for (int j = 0; j < 16; ++j) {
-                    if (this.d[i + j * 16]) {
-                        this.d[i + j * 16] = false;
+                    if (this.c[i + j * 16]) {
+                        this.c[i + j * 16] = false;
                         int k = this.b(i, j);
                         int l = this.x * 16 + i;
                         int i1 = this.z * 16 + j;
@@ -168,19 +206,22 @@ public class Chunk {
                             j1 = i2;
                         }
 
-                        this.f(l, i1, j1);
-                        this.f(l - 1, i1, k);
-                        this.f(l + 1, i1, k);
-                        this.f(l, i1 - 1, k);
-                        this.f(l, i1 + 1, k);
-                        this.v = false;
+                        this.g(l, i1, j1);
+                        this.g(l - 1, i1, k);
+                        this.g(l + 1, i1, k);
+                        this.g(l, i1 - 1, k);
+                        this.g(l, i1 + 1, k);
                     }
                 }
             }
+
+            this.r = false;
         }
+
+        MethodProfiler.a();
     }
 
-    private void f(int i, int j, int k) {
+    private void g(int i, int j, int k) {
         int l = this.world.getHighestBlockYAt(i, j);
 
         if (l > k) {
@@ -191,149 +232,171 @@ public class Chunk {
     }
 
     private void d(int i, int j, int k, int l) {
-        if (l > k && this.world.areChunksLoaded(i, this.world.height / 2, j, 16)) {
+        if (l > k && this.world.areChunksLoaded(i, 0, j, 16)) {
             for (int i1 = k; i1 < l; ++i1) {
                 this.world.b(EnumSkyBlock.SKY, i, i1, j);
             }
 
-            this.q = true;
+            this.l = true;
         }
     }
 
-    private void g(int i, int j, int k) {
-        int l = this.heightMap[k << 4 | i] & 255;
+    private void h(int i, int j, int k) {
+        int l = this.heightMap[k << 4 | i];
         int i1 = l;
 
         if (j > l) {
             i1 = j;
         }
 
-        for (int j1 = i << this.world.heightBitsPlusFour | k << this.world.heightBits; i1 > 0 && Block.lightBlock[this.blocks[j1 + i1 - 1] & 255] == 0; --i1) {
-            ;
+        while (i1 > 0 && this.b(i, i1 - 1, k) == 0) {
+            --i1;
         }
 
         if (i1 != l) {
             this.world.g(i, k, i1, l);
-            this.heightMap[k << 4 | i] = (byte) i1;
-            int k1;
+            this.heightMap[k << 4 | i] = i1;
+            int j1 = this.x * 16 + i;
+            int k1 = this.z * 16 + k;
             int l1;
             int i2;
 
-            if (i1 < this.k) {
-                this.k = i1;
-            } else {
-                k1 = this.world.height - 1;
+            if (!this.world.worldProvider.e) {
+                ChunkSection chunksection;
 
-                for (l1 = 0; l1 < 16; ++l1) {
-                    for (i2 = 0; i2 < 16; ++i2) {
-                        if ((this.heightMap[i2 << 4 | l1] & 255) < k1) {
-                            k1 = this.heightMap[i2 << 4 | l1] & 255;
+                if (i1 < l) {
+                    for (l1 = i1; l1 < l; ++l1) {
+                        chunksection = this.sections[l1 >> 4];
+                        if (chunksection != null) {
+                            chunksection.c(i, l1 & 15, k, 15);
+                            this.world.o((this.x << 4) + i, l1, (this.z << 4) + k);
+                        }
+                    }
+                } else {
+                    for (l1 = l; l1 < i1; ++l1) {
+                        chunksection = this.sections[l1 >> 4];
+                        if (chunksection != null) {
+                            chunksection.c(i, l1 & 15, k, 0);
+                            this.world.o((this.x << 4) + i, l1, (this.z << 4) + k);
                         }
                     }
                 }
 
-                this.k = k1;
-            }
+                l1 = 15;
 
-            k1 = this.x * 16 + i;
-            l1 = this.z * 16 + k;
-            int j2;
-
-            if (!this.world.worldProvider.f) {
-                if (i1 < l) {
-                    for (i2 = i1; i2 < l; ++i2) {
-                        this.h.a(i, i2, k, 15);
-                    }
-                } else {
-                    for (i2 = l; i2 < i1; ++i2) {
-                        this.h.a(i, i2, k, 0);
-                    }
-                }
-
-                for (i2 = 15; i1 > 0 && i2 > 0; this.h.a(i, i1, k, i2)) {
+                while (i1 > 0 && l1 > 0) {
                     --i1;
-                    j2 = Block.lightBlock[this.getTypeId(i, i1, k)];
-                    if (j2 == 0) {
-                        j2 = 1;
+                    i2 = this.b(i, i1, k);
+                    if (i2 == 0) {
+                        i2 = 1;
                     }
 
-                    i2 -= j2;
-                    if (i2 < 0) {
-                        i2 = 0;
+                    l1 -= i2;
+                    if (l1 < 0) {
+                        l1 = 0;
+                    }
+
+                    ChunkSection chunksection1 = this.sections[i1 >> 4];
+
+                    if (chunksection1 != null) {
+                        chunksection1.c(i, i1 & 15, k, l1);
                     }
                 }
             }
 
-            byte b0 = this.heightMap[k << 4 | i];
+            l1 = this.heightMap[k << 4 | i];
+            i2 = l;
+            int j2 = l1;
 
-            j2 = l;
-            int k2 = b0;
-
-            if (b0 < l) {
-                j2 = b0;
-                k2 = l;
+            if (l1 < l) {
+                i2 = l1;
+                j2 = l;
             }
 
-            if (!this.world.worldProvider.f) {
-                this.d(k1 - 1, l1, j2, k2);
-                this.d(k1 + 1, l1, j2, k2);
-                this.d(k1, l1 - 1, j2, k2);
-                this.d(k1, l1 + 1, j2, k2);
-                this.d(k1, l1, j2, k2);
+            if (!this.world.worldProvider.e) {
+                this.d(j1 - 1, k1, i2, j2);
+                this.d(j1 + 1, k1, i2, j2);
+                this.d(j1, k1 - 1, i2, j2);
+                this.d(j1, k1 + 1, i2, j2);
+                this.d(j1, k1, i2, j2);
             }
 
-            this.q = true;
+            this.l = true;
         }
     }
 
+    public int b(int i, int j, int k) {
+        return Block.lightBlock[this.getTypeId(i, j, k)];
+    }
+
     public int getTypeId(int i, int j, int k) {
-        return this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] & 255;
+        ChunkSection chunksection = this.sections[j >> 4];
+
+        return chunksection != null ? chunksection.a(i, j & 15, k) : 0;
+    }
+
+    public int getData(int i, int j, int k) {
+        ChunkSection chunksection = this.sections[j >> 4];
+
+        return chunksection != null ? chunksection.b(i, j & 15, k) : 0;
+    }
+
+    public boolean a(int i, int j, int k, int l) {
+        return this.a(i, j, k, l, 0);
     }
 
     public boolean a(int i, int j, int k, int l, int i1) {
-        byte b0 = (byte) l;
         int j1 = k << 4 | i;
 
-        if (j >= this.c[j1] - 1) {
-            this.c[j1] = -999;
+        if (j >= this.b[j1] - 1) {
+            this.b[j1] = -999;
         }
 
-        int k1 = this.heightMap[k << 4 | i] & 255;
-        int l1 = this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] & 255;
+        int k1 = this.heightMap[j1];
+        int l1 = this.getTypeId(i, j, k);
 
-        if (l1 == l && this.g.a(i, j, k) == i1) {
+        if (l1 == l && this.getData(i, j, k) == i1) {
             return false;
         } else {
+            ChunkSection chunksection = this.sections[j >> 4];
+            boolean flag = false;
+
+            if (chunksection == null) {
+                if (l == 0) {
+                    return false;
+                }
+
+                chunksection = this.sections[j >> 4] = new ChunkSection(j >> 4 << 4);
+                flag = j >= k1;
+            }
+
+            chunksection.a(i, j & 15, k, l);
             int i2 = this.x * 16 + i;
             int j2 = this.z * 16 + k;
 
-            this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] = (byte) (b0 & 255);
             if (l1 != 0) {
                 if (!this.world.isStatic) {
                     Block.byId[l1].remove(this.world, i2, j, j2);
                 } else if (Block.byId[l1] instanceof BlockContainer && l1 != l) {
-                    this.world.n(i2, j, j2);
+                    this.world.q(i2, j, j2);
                 }
             }
 
-            if ((this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] & 255) != l) return false; // CraftBukkit
-
-            this.g.a(i, j, k, i1);
-            if (!this.world.worldProvider.f) {
-                if (Block.lightBlock[b0 & 255] != 0) {
-                    if (j >= k1) {
-                        this.g(i, j + 1, k);
+            chunksection.b(i, j & 15, k, i1);
+            if (flag) {
+                this.initLighting();
+            } else {
+                if (Block.lightBlock[l & 4095] > 0) {
+                    if (j > k1) {
+                        this.h(i, j + 1, k);
                     }
                 } else if (j == k1 - 1) {
-                    this.g(i, j, k);
+                    this.h(i, j, k);
                 }
 
-                this.world.a(EnumSkyBlock.SKY, i2, j, j2, i2, j, j2);
+                this.e(i, k);
             }
 
-            this.world.a(EnumSkyBlock.BLOCK, i2, j, j2, i2, j, j2);
-            this.d(i, k);
-            this.g.a(i, j, k, i1);
             TileEntity tileentity;
 
             if (l != 0) {
@@ -342,159 +405,110 @@ public class Chunk {
                 }
 
                 if (Block.byId[l] instanceof BlockContainer) {
-                    tileentity = this.d(i, j, k);
+                    tileentity = this.e(i, j, k);
                     if (tileentity == null) {
                         tileentity = ((BlockContainer) Block.byId[l]).a_();
                         this.world.setTileEntity(i2, j, j2, tileentity);
                     }
 
                     if (tileentity != null) {
-                        tileentity.d();
+                        tileentity.h();
                     }
                 }
             } else if (l1 > 0 && Block.byId[l1] instanceof BlockContainer) {
-                tileentity = this.d(i, j, k);
+                tileentity = this.e(i, j, k);
                 if (tileentity != null) {
-                    tileentity.d();
+                    tileentity.h();
                 }
             }
 
-            this.q = true;
+            this.l = true;
             return true;
         }
     }
 
-    public boolean a(int i, int j, int k, int l) {
-        byte b0 = (byte) l;
-        int i1 = k << 4 | i;
-
-        if (j >= this.c[i1] - 1) {
-            this.c[i1] = -999;
-        }
-
-        int j1 = this.heightMap[i1] & 255;
-        int k1 = this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] & 255;
-
-        if (k1 == l) {
-            return false;
-        } else {
-            int l1 = this.x * 16 + i;
-            int i2 = this.z * 16 + k;
-
-            this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] = (byte) (b0 & 255);
-            if (k1 != 0) {
-                Block.byId[k1].remove(this.world, l1, j, i2);
-            }
-
-            if ((this.blocks[i << this.world.heightBitsPlusFour | k << this.world.heightBits | j] & 255) != l) return false; // CraftBukkit
-
-            this.g.a(i, j, k, 0);
-            if (Block.lightBlock[b0 & 255] != 0) {
-                if (j >= j1) {
-                    this.g(i, j + 1, k);
-                }
-            } else if (j == j1 - 1) {
-                this.g(i, j, k);
-            }
-
-            this.world.a(EnumSkyBlock.SKY, l1, j, i2, l1, j, i2);
-            this.world.a(EnumSkyBlock.BLOCK, l1, j, i2, l1, j, i2);
-            this.d(i, k);
-            TileEntity tileentity;
-
-            if (l != 0) {
-                if (!this.world.isStatic) {
-                    Block.byId[l].onPlace(this.world, l1, j, i2);
-                }
-
-                if (l > 0 && Block.byId[l] instanceof BlockContainer) {
-                    tileentity = this.d(i, j, k);
-                    if (tileentity == null) {
-                        tileentity = ((BlockContainer) Block.byId[l]).a_();
-                        this.world.setTileEntity(l1, j, i2, tileentity);
-                    }
-
-                    if (tileentity != null) {
-                        tileentity.d();
-                    }
-                }
-            } else if (k1 > 0 && Block.byId[k1] instanceof BlockContainer) {
-                tileentity = this.d(i, j, k);
-                if (tileentity != null) {
-                    tileentity.d();
-                }
-            }
-
-            this.q = true;
-            return true;
-        }
-    }
-
-    public int getData(int i, int j, int k) {
-        return this.g.a(i, j, k);
-    }
-
     public boolean b(int i, int j, int k, int l) {
-        this.q = true;
-        int i1 = this.g.a(i, j, k);
+        ChunkSection chunksection = this.sections[j >> 4];
 
-        if (i1 == l) {
+        if (chunksection == null) {
             return false;
         } else {
-            this.g.a(i, j, k, l);
-            int j1 = this.getTypeId(i, j, k);
+            int i1 = chunksection.b(i, j & 15, k);
 
-            if (j1 > 0 && Block.byId[j1] instanceof BlockContainer) {
-                TileEntity tileentity = this.d(i, j, k);
+            if (i1 == l) {
+                return false;
+            } else {
+                this.l = true;
+                chunksection.b(i, j & 15, k, l);
+                int j1 = chunksection.a(i, j & 15, k);
 
-                if (tileentity != null) {
-                    tileentity.d();
-                    tileentity.p = l;
+                if (j1 > 0 && Block.byId[j1] instanceof BlockContainer) {
+                    TileEntity tileentity = this.e(i, j, k);
+
+                    if (tileentity != null) {
+                        tileentity.h();
+                        tileentity.p = l;
+                    }
                 }
-            }
 
-            return true;
+                return true;
+            }
         }
     }
 
     public int getBrightness(EnumSkyBlock enumskyblock, int i, int j, int k) {
-        return enumskyblock == EnumSkyBlock.SKY ? this.h.a(i, j, k) : (enumskyblock == EnumSkyBlock.BLOCK ? this.i.a(i, j, k) : 0);
+        ChunkSection chunksection = this.sections[j >> 4];
+
+        return chunksection == null ? enumskyblock.c : (enumskyblock == EnumSkyBlock.SKY ? chunksection.c(i, j & 15, k) : (enumskyblock == EnumSkyBlock.BLOCK ? chunksection.d(i, j & 15, k) : enumskyblock.c));
     }
 
     public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) {
-        this.q = true;
+        ChunkSection chunksection = this.sections[j >> 4];
+
+        if (chunksection == null) {
+            chunksection = this.sections[j >> 4] = new ChunkSection(j >> 4 << 4);
+            this.initLighting();
+        }
+
+        this.l = true;
         if (enumskyblock == EnumSkyBlock.SKY) {
-            if (!this.world.worldProvider.f) {
-                this.h.a(i, j, k, l);
+            if (!this.world.worldProvider.e) {
+                chunksection.c(i, j & 15, k, l);
             }
         } else {
             if (enumskyblock != EnumSkyBlock.BLOCK) {
                 return;
             }
 
-            this.i.a(i, j, k, l);
+            chunksection.d(i, j & 15, k, l);
         }
     }
 
     public int c(int i, int j, int k, int l) {
-        int i1 = this.world.worldProvider.f ? 0 : this.h.a(i, j, k);
+        ChunkSection chunksection = this.sections[j >> 4];
 
-        if (i1 > 0) {
-            a = true;
+        if (chunksection == null) {
+            return !this.world.worldProvider.e && l < EnumSkyBlock.SKY.c ? EnumSkyBlock.SKY.c - l : 0;
+        } else {
+            int i1 = this.world.worldProvider.e ? 0 : chunksection.c(i, j & 15, k);
+
+            if (i1 > 0) {
+                a = true;
+            }
+
+            i1 -= l;
+            int j1 = chunksection.d(i, j & 15, k);
+
+            if (j1 > i1) {
+                i1 = j1;
+            }
+
+            return i1;
         }
-
-        i1 -= l;
-        int j1 = this.i.a(i, j, k);
-
-        if (j1 > i1) {
-            i1 = j1;
-        }
-
-        return i1;
     }
 
     public void a(Entity entity) {
-        this.s = true;
+        this.m = true;
         int i = MathHelper.floor(entity.locX / 16.0D);
         int j = MathHelper.floor(entity.locZ / 16.0D);
 
@@ -539,18 +553,18 @@ public class Chunk {
         this.entitySlices[i].remove(entity);
     }
 
-    public boolean c(int i, int j, int k) {
-        return j >= (this.heightMap[k << 4 | i] & 255);
+    public boolean d(int i, int j, int k) {
+        return j > this.heightMap[k << 4 | i];
     }
 
-    public TileEntity d(int i, int j, int k) {
+    public TileEntity e(int i, int j, int k) {
         ChunkPosition chunkposition = new ChunkPosition(i, j, k);
         TileEntity tileentity = (TileEntity) this.tileEntities.get(chunkposition);
 
         if (tileentity == null) {
             int l = this.getTypeId(i, j, k);
 
-            if (!Block.isTileEntity[l]) {
+            if (l <= 0 || !Block.byId[l].n()) {
                 return null;
             }
 
@@ -576,7 +590,7 @@ public class Chunk {
         int k = tileentity.z - this.z * 16;
 
         this.a(i, j, k, tileentity);
-        if (this.e) {
+        if (this.d) {
             this.world.tileEntityList.add(tileentity);
         }
     }
@@ -601,20 +615,20 @@ public class Chunk {
         }
     }
 
-    public void e(int i, int j, int k) {
+    public void f(int i, int j, int k) {
         ChunkPosition chunkposition = new ChunkPosition(i, j, k);
 
-        if (this.e) {
+        if (this.d) {
             TileEntity tileentity = (TileEntity) this.tileEntities.remove(chunkposition);
 
             if (tileentity != null) {
-                tileentity.i();
+                tileentity.j();
             }
         }
     }
 
     public void addEntities() {
-        this.e = true;
+        this.d = true;
         this.world.a(this.tileEntities.values());
 
         for (int i = 0; i < this.entitySlices.length; ++i) {
@@ -623,7 +637,7 @@ public class Chunk {
     }
 
     public void removeEntities() {
-        this.e = false;
+        this.d = false;
         Iterator iterator = this.tileEntities.values().iterator();
 
         while (iterator.hasNext()) {
@@ -652,8 +666,8 @@ public class Chunk {
         }
     }
 
-    public void f() {
-        this.q = true;
+    public void e() {
+        this.l = true;
     }
 
     public void a(Entity entity, AxisAlignedBB axisalignedbb, List list) {
@@ -676,7 +690,7 @@ public class Chunk {
 
                 if (entity1 != entity && entity1.boundingBox.a(axisalignedbb)) {
                     list.add(entity1);
-                    Entity[] aentity = entity1.aR();
+                    Entity[] aentity = entity1.ba();
 
                     if (aentity != null) {
                         for (int i1 = 0; i1 < aentity.length; ++i1) {
@@ -721,80 +735,15 @@ public class Chunk {
     }
 
     public boolean a(boolean flag) {
-        if (this.r) {
-            return false;
-        } else {
-            if (flag) {
-                if (this.s && this.world.getTime() != this.t) {
-                    return true;
-                }
-            } else if (this.s && this.world.getTime() >= this.t + 600L) {
+        if (flag) {
+            if (this.m && this.world.getTime() != this.n) {
                 return true;
             }
-
-            return this.q;
+        } else if (this.m && this.world.getTime() >= this.n + 600L) {
+            return true;
         }
-    }
 
-    public int getData(byte[] abyte, int i, int j, int k, int l, int i1, int j1, int k1) {
-        int l1 = l - i;
-        int i2 = i1 - j;
-        int j2 = j1 - k;
-
-        if (l1 * i2 * j2 == this.blocks.length) {
-            System.arraycopy(this.blocks, 0, abyte, k1, this.blocks.length);
-            k1 += this.blocks.length;
-            System.arraycopy(this.g.a, 0, abyte, k1, this.g.a.length);
-            k1 += this.g.a.length;
-            System.arraycopy(this.i.a, 0, abyte, k1, this.i.a.length);
-            k1 += this.i.a.length;
-            System.arraycopy(this.h.a, 0, abyte, k1, this.h.a.length);
-            k1 += this.h.a.length;
-            return k1;
-        } else {
-            int k2;
-            int l2;
-            int i3;
-            int j3;
-
-            for (k2 = i; k2 < l; ++k2) {
-                for (l2 = k; l2 < j1; ++l2) {
-                    i3 = k2 << this.world.heightBitsPlusFour | l2 << this.world.heightBits | j;
-                    j3 = i1 - j;
-                    System.arraycopy(this.blocks, i3, abyte, k1, j3);
-                    k1 += j3;
-                }
-            }
-
-            for (k2 = i; k2 < l; ++k2) {
-                for (l2 = k; l2 < j1; ++l2) {
-                    i3 = (k2 << this.world.heightBitsPlusFour | l2 << this.world.heightBits | j) >> 1;
-                    j3 = (i1 - j) / 2;
-                    System.arraycopy(this.g.a, i3, abyte, k1, j3);
-                    k1 += j3;
-                }
-            }
-
-            for (k2 = i; k2 < l; ++k2) {
-                for (l2 = k; l2 < j1; ++l2) {
-                    i3 = (k2 << this.world.heightBitsPlusFour | l2 << this.world.heightBits | j) >> 1;
-                    j3 = (i1 - j) / 2;
-                    System.arraycopy(this.i.a, i3, abyte, k1, j3);
-                    k1 += j3;
-                }
-            }
-
-            for (k2 = i; k2 < l; ++k2) {
-                for (l2 = k; l2 < j1; ++l2) {
-                    i3 = (k2 << this.world.heightBitsPlusFour | l2 << this.world.heightBits | j) >> 1;
-                    j3 = (i1 - j) / 2;
-                    System.arraycopy(this.h.a, i3, abyte, k1, j3);
-                    k1 += j3;
-                }
-            }
-
-            return k1;
-        }
+        return this.l;
     }
 
     public Random a(long i) {
@@ -805,8 +754,17 @@ public class Chunk {
         return false;
     }
 
-    public void h() {
-        BlockRegister.a(this.blocks);
+    public void i() {
+        ChunkSection[] achunksection = this.sections;
+        int i = achunksection.length;
+
+        for (int j = 0; j < i; ++j) {
+            ChunkSection chunksection = achunksection[j];
+
+            if (chunksection != null) {
+                chunksection.e();
+            }
+        }
     }
 
     public void a(IChunkProvider ichunkprovider, IChunkProvider ichunkprovider1, int i, int j) {
@@ -827,12 +785,12 @@ public class Chunk {
         }
     }
 
-    public int c(int i, int j) {
+    public int d(int i, int j) {
         int k = i | j << 4;
-        int l = this.c[k];
+        int l = this.b[k];
 
         if (l == -999) {
-            int i1 = this.world.height - 1;
+            int i1 = this.g() + 15;
 
             l = -1;
 
@@ -847,19 +805,116 @@ public class Chunk {
                 }
             }
 
-            this.c[k] = l;
+            this.b[k] = l;
         }
 
         return l;
     }
 
-    public void i() {
-        if (this.v && !this.world.worldProvider.f) {
-            this.k();
+    public void j() {
+        if (this.r && !this.world.worldProvider.e) {
+            this.o();
         }
     }
 
-    public ChunkCoordIntPair j() {
+    public ChunkCoordIntPair k() {
         return new ChunkCoordIntPair(this.x, this.z);
     }
+
+    public boolean c(int i, int j) {
+        if (i < 0) {
+            i = 0;
+        }
+
+        if (j >= 256) {
+            j = 255;
+        }
+
+        for (int k = i; k <= j; k += 16) {
+            ChunkSection chunksection = this.sections[k >> 4];
+
+            if (chunksection != null && !chunksection.a()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public void a(ChunkSection[] achunksection) {
+        this.sections = achunksection;
+    }
+
+    public BiomeBase a(int i, int j, WorldChunkManager worldchunkmanager) {
+        int k = this.q[j << 4 | i] & 255;
+
+        if (k == 255) {
+            BiomeBase biomebase = worldchunkmanager.getBiome((this.x << 4) + i, (this.z << 4) + j);
+
+            k = biomebase.id;
+            this.q[j << 4 | i] = (byte) (k & 255);
+        }
+
+        return BiomeBase.biomes[k] == null ? BiomeBase.PLAINS : BiomeBase.biomes[k];
+    }
+
+    public byte[] l() {
+        return this.q;
+    }
+
+    public void a(byte[] abyte) {
+        this.q = abyte;
+    }
+
+    public void m() {
+        this.s = 0;
+    }
+
+    public void n() {
+        for (int i = 0; i < 8; ++i) {
+            if (this.s >= 4096) {
+                return;
+            }
+
+            int j = this.s % 16;
+            int k = this.s / 16 % 16;
+            int l = this.s / 256;
+
+            ++this.s;
+            int i1 = (this.x << 4) + k;
+            int j1 = (this.z << 4) + l;
+
+            for (int k1 = 0; k1 < 16; ++k1) {
+                int l1 = (j << 4) + k1;
+
+                if (this.sections[j] == null && (k1 == 0 || k1 == 15 || k == 0 || k == 15 || l == 0 || l == 15) || this.sections[j] != null && this.sections[j].a(k, k1, l) == 0) {
+                    if (Block.lightEmission[this.world.getTypeId(i1, l1 - 1, j1)] > 0) {
+                        this.world.v(i1, l1 - 1, j1);
+                    }
+
+                    if (Block.lightEmission[this.world.getTypeId(i1, l1 + 1, j1)] > 0) {
+                        this.world.v(i1, l1 + 1, j1);
+                    }
+
+                    if (Block.lightEmission[this.world.getTypeId(i1 - 1, l1, j1)] > 0) {
+                        this.world.v(i1 - 1, l1, j1);
+                    }
+
+                    if (Block.lightEmission[this.world.getTypeId(i1 + 1, l1, j1)] > 0) {
+                        this.world.v(i1 + 1, l1, j1);
+                    }
+
+                    if (Block.lightEmission[this.world.getTypeId(i1, l1, j1 - 1)] > 0) {
+                        this.world.v(i1, l1, j1 - 1);
+                    }
+
+                    if (Block.lightEmission[this.world.getTypeId(i1, l1, j1 + 1)] > 0) {
+                        this.world.v(i1, l1, j1 + 1);
+                    }
+
+                    this.world.v(i1, l1, j1);
+                }
+            }
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/server/ChunkLoader.java b/src/main/java/net/minecraft/server/ChunkLoader.java
deleted file mode 100644
index 0f1a072b90..0000000000
--- a/src/main/java/net/minecraft/server/ChunkLoader.java
+++ /dev/null
@@ -1,259 +0,0 @@
-package net.minecraft.server;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
-
-public class ChunkLoader implements IChunkLoader {
-
-    private File a;
-    private boolean b;
-
-    public ChunkLoader(File file1, boolean flag) {
-        this.a = file1;
-        this.b = flag;
-    }
-
-    private File a(int i, int j) {
-        String s = "c." + Integer.toString(i, 36) + "." + Integer.toString(j, 36) + ".dat";
-        String s1 = Integer.toString(i & 63, 36);
-        String s2 = Integer.toString(j & 63, 36);
-        File file1 = new File(this.a, s1);
-
-        if (!file1.exists()) {
-            if (!this.b) {
-                return null;
-            }
-
-            file1.mkdir();
-        }
-
-        file1 = new File(file1, s2);
-        if (!file1.exists()) {
-            if (!this.b) {
-                return null;
-            }
-
-            file1.mkdir();
-        }
-
-        file1 = new File(file1, s);
-        return !file1.exists() && !this.b ? null : file1;
-    }
-
-    public Chunk a(World world, int i, int j) {
-        File file1 = this.a(i, j);
-
-        if (file1 != null && file1.exists()) {
-            try {
-                FileInputStream fileinputstream = new FileInputStream(file1);
-                NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a((InputStream) fileinputstream);
-
-                if (!nbttagcompound.hasKey("Level")) {
-                    System.out.println("Chunk file at " + i + "," + j + " is missing level data, skipping");
-                    return null;
-                }
-
-                if (!nbttagcompound.getCompound("Level").hasKey("Blocks")) {
-                    System.out.println("Chunk file at " + i + "," + j + " is missing block data, skipping");
-                    return null;
-                }
-
-                Chunk chunk = a(world, nbttagcompound.getCompound("Level"));
-
-                if (!chunk.a(i, j)) {
-                    System.out.println("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.x + ", " + chunk.z + ")");
-                    nbttagcompound.getCompound("Level").setInt("xPos", i); // CraftBukkit - .getCompound("Level")
-                    nbttagcompound.getCompound("Level").setInt("zPos", j); // CraftBukkit - .getCompound("Level")
-                    chunk = a(world, nbttagcompound.getCompound("Level"));
-                }
-
-                chunk.h();
-                return chunk;
-            } catch (Exception exception) {
-                exception.printStackTrace();
-            }
-        }
-
-        return null;
-    }
-
-    public void a(World world, Chunk chunk) {
-        world.l();
-        File file1 = this.a(chunk.x, chunk.z);
-
-        if (file1.exists()) {
-            WorldData worlddata = world.getWorldData();
-
-            worlddata.b(worlddata.g() - file1.length());
-        }
-
-        try {
-            File file2 = new File(this.a, "tmp_chunk.dat");
-            FileOutputStream fileoutputstream = new FileOutputStream(file2);
-            NBTTagCompound nbttagcompound = new NBTTagCompound();
-            NBTTagCompound nbttagcompound1 = new NBTTagCompound();
-
-            nbttagcompound.set("Level", nbttagcompound1);
-            a(chunk, world, nbttagcompound1);
-            NBTCompressedStreamTools.a(nbttagcompound, (OutputStream) fileoutputstream);
-            fileoutputstream.close();
-            if (file1.exists()) {
-                file1.delete();
-            }
-
-            file2.renameTo(file1);
-            WorldData worlddata1 = world.getWorldData();
-
-            worlddata1.b(worlddata1.g() + file1.length());
-        } catch (Exception exception) {
-            exception.printStackTrace();
-        }
-    }
-
-    public static void a(Chunk chunk, World world, NBTTagCompound nbttagcompound) {
-        world.l();
-        nbttagcompound.setInt("xPos", chunk.x);
-        nbttagcompound.setInt("zPos", chunk.z);
-        nbttagcompound.setLong("LastUpdate", world.getTime());
-        nbttagcompound.setByteArray("Blocks", chunk.blocks);
-        nbttagcompound.setByteArray("Data", chunk.g.a);
-        nbttagcompound.setByteArray("SkyLight", chunk.h.a);
-        nbttagcompound.setByteArray("BlockLight", chunk.i.a);
-        nbttagcompound.setByteArray("HeightMap", chunk.heightMap);
-        nbttagcompound.setBoolean("TerrainPopulated", chunk.done);
-        chunk.s = false;
-        NBTTagList nbttaglist = new NBTTagList();
-
-        Iterator iterator;
-        NBTTagCompound nbttagcompound1;
-
-        for (int i = 0; i < chunk.entitySlices.length; ++i) {
-            iterator = chunk.entitySlices[i].iterator();
-
-            while (iterator.hasNext()) {
-                Entity entity = (Entity) iterator.next();
-
-                chunk.s = true;
-                nbttagcompound1 = new NBTTagCompound();
-                if (entity.c(nbttagcompound1)) {
-                    nbttaglist.add(nbttagcompound1);
-                }
-            }
-        }
-
-        nbttagcompound.set("Entities", nbttaglist);
-        NBTTagList nbttaglist1 = new NBTTagList();
-
-        iterator = chunk.tileEntities.values().iterator();
-
-        while (iterator.hasNext()) {
-            TileEntity tileentity = (TileEntity) iterator.next();
-
-            nbttagcompound1 = new NBTTagCompound();
-            tileentity.b(nbttagcompound1);
-            nbttaglist1.add(nbttagcompound1);
-        }
-
-        nbttagcompound.set("TileEntities", nbttaglist1);
-        List list = world.a(chunk, false);
-
-        if (list != null) {
-            long j = world.getTime();
-            NBTTagList nbttaglist2 = new NBTTagList();
-            Iterator iterator1 = list.iterator();
-
-            while (iterator1.hasNext()) {
-                NextTickListEntry nextticklistentry = (NextTickListEntry) iterator1.next();
-                NBTTagCompound nbttagcompound2 = new NBTTagCompound();
-
-                nbttagcompound2.setInt("i", nextticklistentry.d);
-                nbttagcompound2.setInt("x", nextticklistentry.a);
-                nbttagcompound2.setInt("y", nextticklistentry.b);
-                nbttagcompound2.setInt("z", nextticklistentry.c);
-                nbttagcompound2.setInt("t", (int) (nextticklistentry.e - j));
-                nbttaglist2.add(nbttagcompound2);
-            }
-
-            nbttagcompound.set("TileTicks", nbttaglist2);
-        }
-    }
-
-    public static Chunk a(World world, NBTTagCompound nbttagcompound) {
-        int i = nbttagcompound.getInt("xPos");
-        int j = nbttagcompound.getInt("zPos");
-        Chunk chunk = new Chunk(world, i, j);
-
-        chunk.blocks = nbttagcompound.getByteArray("Blocks");
-        chunk.g = new NibbleArray(nbttagcompound.getByteArray("Data"), world.heightBits);
-        chunk.h = new NibbleArray(nbttagcompound.getByteArray("SkyLight"), world.heightBits);
-        chunk.i = new NibbleArray(nbttagcompound.getByteArray("BlockLight"), world.heightBits);
-        chunk.heightMap = nbttagcompound.getByteArray("HeightMap");
-        chunk.done = nbttagcompound.getBoolean("TerrainPopulated");
-        if (!chunk.g.a()) {
-            chunk.g = new NibbleArray(chunk.blocks.length, world.heightBits);
-        }
-
-        if (chunk.heightMap == null || !chunk.h.a()) {
-            chunk.heightMap = new byte[256];
-            chunk.h = new NibbleArray(chunk.blocks.length, world.heightBits);
-            chunk.initLighting();
-        }
-
-        if (!chunk.i.a()) {
-            chunk.i = new NibbleArray(chunk.blocks.length, world.heightBits);
-            chunk.a();
-        }
-
-        NBTTagList nbttaglist = nbttagcompound.getList("Entities");
-
-        if (nbttaglist != null) {
-            for (int k = 0; k < nbttaglist.size(); ++k) {
-                NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.get(k);
-                Entity entity = EntityTypes.a(nbttagcompound1, world);
-
-                chunk.s = true;
-                if (entity != null) {
-                    chunk.a(entity);
-                }
-            }
-        }
-
-        NBTTagList nbttaglist1 = nbttagcompound.getList("TileEntities");
-
-        if (nbttaglist1 != null) {
-            for (int l = 0; l < nbttaglist1.size(); ++l) {
-                NBTTagCompound nbttagcompound2 = (NBTTagCompound) nbttaglist1.get(l);
-                TileEntity tileentity = TileEntity.c(nbttagcompound2);
-
-                if (tileentity != null) {
-                    chunk.a(tileentity);
-                }
-            }
-        }
-
-        if (nbttagcompound.hasKey("TileTicks")) {
-            NBTTagList nbttaglist2 = nbttagcompound.getList("TileTicks");
-
-            if (nbttaglist2 != null) {
-                for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) {
-                    NBTTagCompound nbttagcompound3 = (NBTTagCompound) nbttaglist2.get(i1);
-
-                    world.d(nbttagcompound3.getInt("x"), nbttagcompound3.getInt("y"), nbttagcompound3.getInt("z"), nbttagcompound3.getInt("i"), nbttagcompound3.getInt("t"));
-                }
-            }
-        }
-
-        return chunk;
-    }
-
-    public void a() {}
-
-    public void b() {}
-
-    public void b(World world, Chunk chunk) {}
-}
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index b345f5dbb4..bc21b8a06d 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -32,7 +32,7 @@ public class ChunkProviderServer implements IChunkProvider {
     // CraftBukkit end
 
     public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) {
-        this.emptyChunk = new EmptyChunk(worldserver, new byte[256 * worldserver.height], 0, 0);
+        this.emptyChunk = new EmptyChunk(worldserver, 0, 0);
         this.world = worldserver;
         this.e = ichunkloader;
         this.chunkProvider = ichunkprovider;
@@ -135,7 +135,7 @@ public class ChunkProviderServer implements IChunkProvider {
                 Chunk chunk = this.e.a(this.world, i, j);
 
                 if (chunk != null) {
-                    chunk.t = this.world.getTime();
+                    chunk.n = this.world.getTime();
                 }
 
                 return chunk;
@@ -159,7 +159,7 @@ public class ChunkProviderServer implements IChunkProvider {
     public void saveChunk(Chunk chunk) { // CraftBukkit - private -> public
         if (this.e != null) {
             try {
-                chunk.t = this.world.getTime();
+                chunk.n = this.world.getTime();
                 this.e.a(this.world, chunk);
             } catch (Exception ioexception) { // CraftBukkit - IOException -> Exception
                 ioexception.printStackTrace();
@@ -193,7 +193,7 @@ public class ChunkProviderServer implements IChunkProvider {
                 this.world.getServer().getPluginManager().callEvent(new ChunkPopulateEvent(chunk.bukkitChunk));
                 // CraftBukkit end
 
-                chunk.f();
+                chunk.e();
             }
         }
     }
@@ -204,13 +204,13 @@ public class ChunkProviderServer implements IChunkProvider {
         for (int j = 0; j < this.chunkList.size(); ++j) {
             Chunk chunk = (Chunk) this.chunkList.get(j);
 
-            if (flag && !chunk.r) {
+            if (flag) {
                 this.saveChunkNOP(chunk);
             }
 
             if (chunk.a(flag)) {
                 this.saveChunk(chunk);
-                chunk.q = false;
+                chunk.l = false;
                 ++i;
                 if (i == 24 && !flag) {
                     return false;
@@ -266,7 +266,7 @@ public class ChunkProviderServer implements IChunkProvider {
     }
 
     public String d() {
-        return "ServerChunkCache: " + this.chunks.values().size() + " Drop: " + this.unloadQueue.size();
+        return "ServerChunkCache: " + this.chunks.values().size() + " Drop: " + this.unloadQueue.size(); // CraftBukkit
     }
 
     public List getMobsFor(EnumCreatureType enumcreaturetype, int i, int j, int k) {
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 6dc6ebd577..d27f194819 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -1,8 +1,14 @@
 package net.minecraft.server;
 
-import java.io.*;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException; // CraftBukkit
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -43,43 +49,47 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
             nbttagcompound = NBTCompressedStreamTools.a((DataInput) datainputstream);
         }
 
+        return this.a(world, i, j, nbttagcompound);
+    }
+
+    protected Chunk a(World world, int i, int j, NBTTagCompound nbttagcompound) {
         if (!nbttagcompound.hasKey("Level")) {
             System.out.println("Chunk file at " + i + "," + j + " is missing level data, skipping");
             return null;
-        } else if (!nbttagcompound.getCompound("Level").hasKey("Blocks")) {
+        } else if (!nbttagcompound.getCompound("Level").hasKey("Sections")) {
             System.out.println("Chunk file at " + i + "," + j + " is missing block data, skipping");
             return null;
         } else {
-            Chunk chunk = ChunkLoader.a(world, nbttagcompound.getCompound("Level"));
+            Chunk chunk = this.a(world, nbttagcompound.getCompound("Level"));
 
             if (!chunk.a(i, j)) {
                 System.out.println("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.x + ", " + chunk.z + ")");
                 nbttagcompound.getCompound("Level").setInt("xPos", i); // CraftBukkit - .getCompound("Level")
                 nbttagcompound.getCompound("Level").setInt("zPos", j); // CraftBukkit - .getCompound("Level")
-                chunk = ChunkLoader.a(world, nbttagcompound.getCompound("Level"));
+                chunk = this.a(world, nbttagcompound.getCompound("Level"));
             }
 
-            chunk.h();
+            chunk.i();
             return chunk;
         }
     }
 
     public void a(World world, Chunk chunk) {
-        world.l();
+        world.m();
 
         try {
             NBTTagCompound nbttagcompound = new NBTTagCompound();
             NBTTagCompound nbttagcompound1 = new NBTTagCompound();
 
             nbttagcompound.set("Level", nbttagcompound1);
-            ChunkLoader.a(chunk, world, nbttagcompound1);
-            this.a(chunk.j(), nbttagcompound);
+            this.a(chunk, world, nbttagcompound1);
+            this.a(chunk.k(), nbttagcompound);
         } catch (Exception exception) {
             exception.printStackTrace();
         }
     }
 
-    private void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
+    protected void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
         Object object = this.c;
 
         synchronized (this.c) {
@@ -134,4 +144,169 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
     public void a() {}
 
     public void b() {}
+
+    private void a(Chunk chunk, World world, NBTTagCompound nbttagcompound) {
+        world.m();
+        nbttagcompound.setInt("xPos", chunk.x);
+        nbttagcompound.setInt("zPos", chunk.z);
+        nbttagcompound.setLong("LastUpdate", world.getTime());
+        nbttagcompound.setIntArray("HeightMap", chunk.heightMap);
+        nbttagcompound.setBoolean("TerrainPopulated", chunk.done);
+        ChunkSection[] achunksection = chunk.h();
+        NBTTagList nbttaglist = new NBTTagList("Sections");
+        ChunkSection[] achunksection1 = achunksection;
+        int i = achunksection.length;
+
+        NBTTagCompound nbttagcompound1;
+
+        for (int j = 0; j < i; ++j) {
+            ChunkSection chunksection = achunksection1[j];
+
+            if (chunksection != null && chunksection.f() != 0) {
+                nbttagcompound1 = new NBTTagCompound();
+                nbttagcompound1.setByte("Y", (byte) (chunksection.c() >> 4 & 255));
+                nbttagcompound1.setByteArray("Blocks", chunksection.g());
+                if (chunksection.h() != null) {
+                    nbttagcompound1.setByteArray("Add", chunksection.h().a);
+                }
+
+                nbttagcompound1.setByteArray("Data", chunksection.i().a);
+                nbttagcompound1.setByteArray("SkyLight", chunksection.k().a);
+                nbttagcompound1.setByteArray("BlockLight", chunksection.j().a);
+                nbttaglist.add(nbttagcompound1);
+            }
+        }
+
+        nbttagcompound.set("Sections", nbttaglist);
+        nbttagcompound.setByteArray("Biomes", chunk.l());
+        chunk.m = false;
+        NBTTagList nbttaglist1 = new NBTTagList();
+
+        Iterator iterator;
+
+        for (i = 0; i < chunk.entitySlices.length; ++i) {
+            iterator = chunk.entitySlices[i].iterator();
+
+            while (iterator.hasNext()) {
+                Entity entity = (Entity) iterator.next();
+
+                chunk.m = true;
+                nbttagcompound1 = new NBTTagCompound();
+                if (entity.c(nbttagcompound1)) {
+                    nbttaglist1.add(nbttagcompound1);
+                }
+            }
+        }
+
+        nbttagcompound.set("Entities", nbttaglist1);
+        NBTTagList nbttaglist2 = new NBTTagList();
+
+        iterator = chunk.tileEntities.values().iterator();
+
+        while (iterator.hasNext()) {
+            TileEntity tileentity = (TileEntity) iterator.next();
+
+            nbttagcompound1 = new NBTTagCompound();
+            tileentity.b(nbttagcompound1);
+            nbttaglist2.add(nbttagcompound1);
+        }
+
+        nbttagcompound.set("TileEntities", nbttaglist2);
+        List list = world.a(chunk, false);
+
+        if (list != null) {
+            long k = world.getTime();
+            NBTTagList nbttaglist3 = new NBTTagList();
+            Iterator iterator1 = list.iterator();
+
+            while (iterator1.hasNext()) {
+                NextTickListEntry nextticklistentry = (NextTickListEntry) iterator1.next();
+                NBTTagCompound nbttagcompound2 = new NBTTagCompound();
+
+                nbttagcompound2.setInt("i", nextticklistentry.d);
+                nbttagcompound2.setInt("x", nextticklistentry.a);
+                nbttagcompound2.setInt("y", nextticklistentry.b);
+                nbttagcompound2.setInt("z", nextticklistentry.c);
+                nbttagcompound2.setInt("t", (int) (nextticklistentry.e - k));
+                nbttaglist3.add(nbttagcompound2);
+            }
+
+            nbttagcompound.set("TileTicks", nbttaglist3);
+        }
+    }
+
+    private Chunk a(World world, NBTTagCompound nbttagcompound) {
+        int i = nbttagcompound.getInt("xPos");
+        int j = nbttagcompound.getInt("zPos");
+        Chunk chunk = new Chunk(world, i, j);
+
+        chunk.heightMap = nbttagcompound.getIntArray("HeightMap");
+        chunk.done = nbttagcompound.getBoolean("TerrainPopulated");
+        NBTTagList nbttaglist = nbttagcompound.getList("Sections");
+        byte b0 = 16;
+        ChunkSection[] achunksection = new ChunkSection[b0];
+
+        for (int k = 0; k < nbttaglist.size(); ++k) {
+            NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttaglist.get(k);
+            byte b1 = nbttagcompound1.getByte("Y");
+            ChunkSection chunksection = new ChunkSection(b1 << 4);
+
+            chunksection.a(nbttagcompound1.getByteArray("Blocks"));
+            if (nbttagcompound1.hasKey("Add")) {
+                chunksection.a(new NibbleArray(nbttagcompound1.getByteArray("Add"), 4));
+            }
+
+            chunksection.b(new NibbleArray(nbttagcompound1.getByteArray("Data"), 4));
+            chunksection.d(new NibbleArray(nbttagcompound1.getByteArray("SkyLight"), 4));
+            chunksection.c(new NibbleArray(nbttagcompound1.getByteArray("BlockLight"), 4));
+            chunksection.d();
+            achunksection[b1] = chunksection;
+        }
+
+        chunk.a(achunksection);
+        if (nbttagcompound.hasKey("Biomes")) {
+            chunk.a(nbttagcompound.getByteArray("Biomes"));
+        }
+
+        NBTTagList nbttaglist1 = nbttagcompound.getList("Entities");
+
+        if (nbttaglist1 != null) {
+            for (int l = 0; l < nbttaglist1.size(); ++l) {
+                NBTTagCompound nbttagcompound2 = (NBTTagCompound) nbttaglist1.get(l);
+                Entity entity = EntityTypes.a(nbttagcompound2, world);
+
+                chunk.m = true;
+                if (entity != null) {
+                    chunk.a(entity);
+                }
+            }
+        }
+
+        NBTTagList nbttaglist2 = nbttagcompound.getList("TileEntities");
+
+        if (nbttaglist2 != null) {
+            for (int i1 = 0; i1 < nbttaglist2.size(); ++i1) {
+                NBTTagCompound nbttagcompound3 = (NBTTagCompound) nbttaglist2.get(i1);
+                TileEntity tileentity = TileEntity.c(nbttagcompound3);
+
+                if (tileentity != null) {
+                    chunk.a(tileentity);
+                }
+            }
+        }
+
+        if (nbttagcompound.hasKey("TileTicks")) {
+            NBTTagList nbttaglist3 = nbttagcompound.getList("TileTicks");
+
+            if (nbttaglist3 != null) {
+                for (int j1 = 0; j1 < nbttaglist3.size(); ++j1) {
+                    NBTTagCompound nbttagcompound4 = (NBTTagCompound) nbttaglist3.get(j1);
+
+                    world.d(nbttagcompound4.getInt("x"), nbttagcompound4.getInt("y"), nbttagcompound4.getInt("z"), nbttagcompound4.getInt("i"), nbttagcompound4.getInt("t"));
+                }
+            }
+        }
+
+        return chunk;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/Container.java b/src/main/java/net/minecraft/server/Container.java
index 63ec63747a..c190fee45c 100644
--- a/src/main/java/net/minecraft/server/Container.java
+++ b/src/main/java/net/minecraft/server/Container.java
@@ -177,7 +177,7 @@ public abstract class Container {
                                 slot1.set((ItemStack) null);
                             }
 
-                            slot1.b(playerinventory.getCarried());
+                            slot1.c(playerinventory.getCarried());
                         } else if (slot1.isAllowed(itemstack3)) {
                             if (itemstack2.id == itemstack3.id && (!itemstack2.usesData() || itemstack2.getData() == itemstack3.getData()) && ItemStack.equals(itemstack2, itemstack3)) {
                                 l = j == 0 ? itemstack3.count : 1;
@@ -203,12 +203,12 @@ public abstract class Container {
                             l = itemstack2.count;
                             if (l > 0 && l + itemstack3.count <= itemstack3.getMaxStackSize()) {
                                 itemstack3.count += l;
-                                itemstack2.a(l);
+                                itemstack2 = slot1.a(l);
                                 if (itemstack2.count == 0) {
                                     slot1.set((ItemStack) null);
                                 }
 
-                                slot1.b(playerinventory.getCarried());
+                                slot1.c(playerinventory.getCarried());
                             }
                         }
                     }
diff --git a/src/main/java/net/minecraft/server/ContainerBrewingStand.java b/src/main/java/net/minecraft/server/ContainerBrewingStand.java
index 5f1128c78c..b7d11dbae5 100644
--- a/src/main/java/net/minecraft/server/ContainerBrewingStand.java
+++ b/src/main/java/net/minecraft/server/ContainerBrewingStand.java
@@ -37,7 +37,7 @@ public class ContainerBrewingStand extends Container {
 
     public void addSlotListener(ICrafting icrafting) {
         super.addSlotListener(icrafting);
-        icrafting.setContainerData(this, 0, this.brewingStand.h());
+        icrafting.setContainerData(this, 0, this.brewingStand.i());
     }
 
     public void a() {
@@ -46,12 +46,12 @@ public class ContainerBrewingStand extends Container {
         for (int i = 0; i < this.listeners.size(); ++i) {
             ICrafting icrafting = (ICrafting) this.listeners.get(i);
 
-            if (this.b != this.brewingStand.h()) {
-                icrafting.setContainerData(this, 0, this.brewingStand.h());
+            if (this.b != this.brewingStand.i()) {
+                icrafting.setContainerData(this, 0, this.brewingStand.i());
             }
         }
 
-        this.b = this.brewingStand.h();
+        this.b = this.brewingStand.i();
     }
 
     public boolean b(EntityHuman entityhuman) {
@@ -79,8 +79,12 @@ public class ContainerBrewingStand extends Container {
                 } else if (!this.a(itemstack1, 4, 40, false)) {
                     return null;
                 }
-            } else if (!this.a(itemstack1, 4, 40, true)) {
-                return null;
+            } else {
+                if (!this.a(itemstack1, 4, 40, true)) {
+                    return null;
+                }
+
+                slot.a(itemstack1, itemstack);
             }
 
             if (itemstack1.count == 0) {
@@ -93,7 +97,7 @@ public class ContainerBrewingStand extends Container {
                 return null;
             }
 
-            slot.b(itemstack1);
+            slot.c(itemstack1);
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/ContainerDispenser.java b/src/main/java/net/minecraft/server/ContainerDispenser.java
index 40763017fc..b73e968da4 100644
--- a/src/main/java/net/minecraft/server/ContainerDispenser.java
+++ b/src/main/java/net/minecraft/server/ContainerDispenser.java
@@ -71,7 +71,7 @@ public class ContainerDispenser extends Container {
                 return null;
             }
 
-            slot.b(itemstack1);
+            slot.c(itemstack1);
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/ContainerEnchantTable.java b/src/main/java/net/minecraft/server/ContainerEnchantTable.java
index 83c3fc1a71..1a6619b339 100644
--- a/src/main/java/net/minecraft/server/ContainerEnchantTable.java
+++ b/src/main/java/net/minecraft/server/ContainerEnchantTable.java
@@ -146,9 +146,9 @@ public class ContainerEnchantTable extends Container {
     public boolean a(EntityHuman entityhuman, int i) {
         ItemStack itemstack = this.enchantSlots.getItem(0);
 
-        if (this.costs[i] > 0 && itemstack != null && entityhuman.expLevel >= this.costs[i]) {
+        if (this.costs[i] > 0 && itemstack != null && (entityhuman.expLevel >= this.costs[i] || entityhuman.abilities.canInstantlyBuild)) {
             if (!this.world.isStatic) {
-                List list = EnchantmentManager.a(this.l, itemstack, this.costs[i]);
+                List list = EnchantmentManager.b(this.l, itemstack, this.costs[i]);
 
                 // CraftBukkit start
                 Map<org.bukkit.enchantments.Enchantment, Integer> enchants = new HashMap<org.bukkit.enchantments.Enchantment, Integer>();
@@ -189,7 +189,7 @@ public class ContainerEnchantTable extends Container {
     public void a(EntityHuman entityhuman) {
         super.a(entityhuman);
         if (!this.world.isStatic) {
-            ItemStack itemstack = this.enchantSlots.getItem(0);
+            ItemStack itemstack = this.enchantSlots.splitWithoutUpdate(0);
 
             if (itemstack != null) {
                 entityhuman.drop(itemstack);
@@ -228,7 +228,7 @@ public class ContainerEnchantTable extends Container {
                 return null;
             }
 
-            slot.b(itemstack1);
+            slot.c(itemstack1);
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/ContainerEnchantTableSubcontainer.java b/src/main/java/net/minecraft/server/ContainerEnchantTableSubcontainer.java
index a782cf68d8..daf85bcc63 100644
--- a/src/main/java/net/minecraft/server/ContainerEnchantTableSubcontainer.java
+++ b/src/main/java/net/minecraft/server/ContainerEnchantTableSubcontainer.java
@@ -73,6 +73,17 @@ public class ContainerEnchantTableSubcontainer implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         this.items[i] = itemstack;
         if (itemstack != null && itemstack.count > this.getMaxStackSize()) {
diff --git a/src/main/java/net/minecraft/server/ContainerFurnace.java b/src/main/java/net/minecraft/server/ContainerFurnace.java
index b488a90141..9e41069a1b 100644
--- a/src/main/java/net/minecraft/server/ContainerFurnace.java
+++ b/src/main/java/net/minecraft/server/ContainerFurnace.java
@@ -94,6 +94,8 @@ public class ContainerFurnace extends Container {
                 if (!this.a(itemstack1, 3, 39, true)) {
                     return null;
                 }
+
+                slot.a(itemstack1, itemstack);
             } else if (i >= 3 && i < 30) {
                 if (!this.a(itemstack1, 30, 39, false)) {
                     return null;
@@ -116,7 +118,7 @@ public class ContainerFurnace extends Container {
                 return null;
             }
 
-            slot.b(itemstack1);
+            slot.c(itemstack1);
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/ContainerPlayer.java b/src/main/java/net/minecraft/server/ContainerPlayer.java
index 458d1be383..809f8d408a 100644
--- a/src/main/java/net/minecraft/server/ContainerPlayer.java
+++ b/src/main/java/net/minecraft/server/ContainerPlayer.java
@@ -72,13 +72,14 @@ public class ContainerPlayer extends Container {
         super.a(entityhuman);
 
         for (int i = 0; i < 4; ++i) {
-            ItemStack itemstack = this.craftInventory.getItem(i);
+            ItemStack itemstack = this.craftInventory.splitWithoutUpdate(i);
 
             if (itemstack != null) {
                 entityhuman.drop(itemstack);
-                this.craftInventory.setItem(i, (ItemStack) null);
             }
         }
+
+        this.resultInventory.setItem(0, (ItemStack) null);
     }
 
     public boolean b(EntityHuman entityhuman) {
@@ -97,6 +98,8 @@ public class ContainerPlayer extends Container {
                 if (!this.a(itemstack1, 9, 45, true)) {
                     return null;
                 }
+
+                slot.a(itemstack1, itemstack);
             } else if (i >= 9 && i < 36) {
                 if (!this.a(itemstack1, 36, 45, false)) {
                     return null;
@@ -119,7 +122,7 @@ public class ContainerPlayer extends Container {
                 return null;
             }
 
-            slot.b(itemstack1);
+            slot.c(itemstack1);
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/ContainerWorkbench.java b/src/main/java/net/minecraft/server/ContainerWorkbench.java
index 5ed8848fa9..d40ab0737d 100644
--- a/src/main/java/net/minecraft/server/ContainerWorkbench.java
+++ b/src/main/java/net/minecraft/server/ContainerWorkbench.java
@@ -71,7 +71,7 @@ public class ContainerWorkbench extends Container {
         super.a(entityhuman);
         if (!this.c.isStatic) {
             for (int i = 0; i < 9; ++i) {
-                ItemStack itemstack = this.craftInventory.getItem(i);
+                ItemStack itemstack = this.craftInventory.splitWithoutUpdate(i);
 
                 if (itemstack != null) {
                     entityhuman.drop(itemstack);
@@ -97,6 +97,8 @@ public class ContainerWorkbench extends Container {
                 if (!this.a(itemstack1, 10, 46, true)) {
                     return null;
                 }
+
+                slot.a(itemstack1, itemstack);
             } else if (i >= 10 && i < 37) {
                 if (!this.a(itemstack1, 37, 46, false)) {
                     return null;
@@ -119,7 +121,7 @@ public class ContainerWorkbench extends Container {
                 return null;
             }
 
-            slot.b(itemstack1);
+            slot.c(itemstack1);
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java
index ca95ec066e..d1c59a47ae 100644
--- a/src/main/java/net/minecraft/server/CraftingManager.java
+++ b/src/main/java/net/minecraft/server/CraftingManager.java
@@ -44,13 +44,13 @@ public class CraftingManager {
         this.registerShapedRecipe(new ItemStack(Block.GLOWSTONE, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.GLOWSTONE_DUST});
         this.registerShapedRecipe(new ItemStack(Block.WOOL, 1), new Object[] { "##", "##", Character.valueOf('#'), Item.STRING});
         this.registerShapedRecipe(new ItemStack(Block.TNT, 1), new Object[] { "X#X", "#X#", "X#X", Character.valueOf('X'), Item.SULPHUR, Character.valueOf('#'), Block.SAND});
-        this.registerShapedRecipe(new ItemStack(Block.STEP, 3, 3), new Object[] { "###", Character.valueOf('#'), Block.COBBLESTONE});
-        this.registerShapedRecipe(new ItemStack(Block.STEP, 3, 0), new Object[] { "###", Character.valueOf('#'), Block.STONE});
-        this.registerShapedRecipe(new ItemStack(Block.STEP, 3, 1), new Object[] { "###", Character.valueOf('#'), Block.SANDSTONE});
-        this.registerShapedRecipe(new ItemStack(Block.STEP, 3, 2), new Object[] { "###", Character.valueOf('#'), Block.WOOD});
-        this.registerShapedRecipe(new ItemStack(Block.STEP, 3, 4), new Object[] { "###", Character.valueOf('#'), Block.BRICK});
-        this.registerShapedRecipe(new ItemStack(Block.STEP, 3, 5), new Object[] { "###", Character.valueOf('#'), Block.SMOOTH_BRICK});
-        this.registerShapedRecipe(new ItemStack(Block.LADDER, 2), new Object[] { "# #", "###", "# #", Character.valueOf('#'), Item.STICK});
+        this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 3), new Object[] { "###", Character.valueOf('#'), Block.COBBLESTONE});
+        this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 0), new Object[] { "###", Character.valueOf('#'), Block.STONE});
+        this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 1), new Object[] { "###", Character.valueOf('#'), Block.SANDSTONE});
+        this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 2), new Object[] { "###", Character.valueOf('#'), Block.WOOD});
+        this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 4), new Object[] { "###", Character.valueOf('#'), Block.BRICK});
+        this.registerShapedRecipe(new ItemStack(Block.STEP, 6, 5), new Object[] { "###", Character.valueOf('#'), Block.SMOOTH_BRICK});
+        this.registerShapedRecipe(new ItemStack(Block.LADDER, 3), new Object[] { "# #", "###", "# #", Character.valueOf('#'), Item.STICK});
         this.registerShapedRecipe(new ItemStack(Item.WOOD_DOOR, 1), new Object[] { "##", "##", "##", Character.valueOf('#'), Block.WOOD});
         this.registerShapedRecipe(new ItemStack(Block.TRAP_DOOR, 2), new Object[] { "###", "###", Character.valueOf('#'), Block.WOOD});
         this.registerShapedRecipe(new ItemStack(Item.IRON_DOOR, 1), new Object[] { "##", "##", "##", Character.valueOf('#'), Item.IRON_INGOT});
@@ -99,6 +99,8 @@ public class CraftingManager {
         this.registerShapedRecipe(new ItemStack(Item.BED, 1), new Object[] { "###", "XXX", Character.valueOf('#'), Block.WOOL, Character.valueOf('X'), Block.WOOD});
         this.registerShapedRecipe(new ItemStack(Block.ENCHANTMENT_TABLE, 1), new Object[] { " B ", "D#D", "###", Character.valueOf('#'), Block.OBSIDIAN, Character.valueOf('B'), Item.BOOK, Character.valueOf('D'), Item.DIAMOND});
         this.registerShapelessRecipe(new ItemStack(Item.EYE_OF_ENDER, 1), new Object[] { Item.ENDER_PEARL, Item.BLAZE_POWDER});
+        this.registerShapelessRecipe(new ItemStack(Item.FIREBALL, 3), new Object[] { Item.SULPHUR, Item.BLAZE_POWDER, Item.COAL});
+        this.registerShapelessRecipe(new ItemStack(Item.FIREBALL, 3), new Object[] { Item.SULPHUR, Item.BLAZE_POWDER, new ItemStack(Item.COAL, 1, 1)});
         //Collections.sort(this.b, new RecipeSorter(this)); // CraftBukkit - removed; see below
         this.sort(); // CraftBukkit - moved sort to a separate method
         System.out.println(this.recipies.size() + " recipes");
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 3638f861ec..bc093075a1 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -191,11 +191,11 @@ public abstract class Entity {
         this.boundingBox.c(d0 - (double) f, d1 - (double) this.height + (double) this.bO, d2 - (double) f, d0 + (double) f, d1 - (double) this.height + (double) this.bO + (double) f1, d2 + (double) f);
     }
 
-    public void y_() {
-        this.am();
+    public void G_() {
+        this.az();
     }
 
-    public void am() {
+    public void az() {
         // MethodProfiler.a("entityBaseTick"); // CraftBukkit - not in production code
         if (this.vehicle != null && this.vehicle.dead) {
             this.vehicle = null;
@@ -210,7 +210,7 @@ public abstract class Entity {
         this.lastYaw = this.yaw;
         int i;
 
-        if (this.isSprinting()) {
+        if (this.isSprinting() && !this.aT()) {
             int j = MathHelper.floor(this.locX);
             int k = MathHelper.floor(this.locY - 0.20000000298023224D - (double) this.height);
 
@@ -222,7 +222,7 @@ public abstract class Entity {
             }
         }
 
-        if (this.i_()) {
+        if (this.h_()) {
             if (!this.bV && !this.justCreated) {
                 float f = MathHelper.sqrt(this.motX * this.motX * 0.20000000298023224D + this.motY * this.motY + this.motZ * this.motZ * 0.20000000298023224D) * 0.2F;
 
@@ -284,13 +284,13 @@ public abstract class Entity {
             }
         }
 
-        if (this.aL()) {
-            this.aG();
+        if (this.aU()) {
+            this.aP();
             this.fallDistance *= 0.5F;
         }
 
         if (this.locY < -64.0D) {
-            this.az();
+            this.aH();
         }
 
         if (!this.world.isStatic) {
@@ -302,7 +302,7 @@ public abstract class Entity {
         // MethodProfiler.a(); // CraftBukkit - not in production code
     }
 
-    protected void aG() {
+    protected void aP() {
         if (!this.fireProof) {
             // CraftBukkit start - fallen in lava TODO: this event spams!
             if (this instanceof EntityLiving) {
@@ -352,7 +352,7 @@ public abstract class Entity {
         this.fireTicks = 0;
     }
 
-    protected void az() {
+    protected void aH() {
         this.die();
     }
 
@@ -389,7 +389,7 @@ public abstract class Entity {
             double d6 = d1;
             double d7 = d2;
             AxisAlignedBB axisalignedbb = this.boundingBox.clone();
-            boolean flag = this.onGround && this.isSneaking();
+            boolean flag = this.onGround && this.isSneaking() && this instanceof EntityHuman;
 
             if (flag) {
                 double d8;
@@ -618,7 +618,7 @@ public abstract class Entity {
                 }
             }
 
-            boolean flag2 = this.aJ();
+            boolean flag2 = this.aS();
 
             if (this.world.d(this.boundingBox.shrink(0.0010D, 0.0010D, 0.0010D))) {
                 this.burn(1);
@@ -683,7 +683,7 @@ public abstract class Entity {
                     }
                 }
 
-                this.b(this.fallDistance);
+                this.a(this.fallDistance);
                 this.fallDistance = 0.0F;
             }
         } else if (d0 < 0.0D) {
@@ -691,7 +691,7 @@ public abstract class Entity {
         }
     }
 
-    public AxisAlignedBB h_() {
+    public AxisAlignedBB h() {
         return null;
     }
 
@@ -717,21 +717,21 @@ public abstract class Entity {
         return this.fireProof;
     }
 
-    protected void b(float f) {
+    protected void a(float f) {
         if (this.passenger != null) {
-            this.passenger.b(f);
+            this.passenger.a(f);
         }
     }
 
-    public boolean aJ() {
-        return this.bV || this.world.v(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
+    public boolean aS() {
+        return this.bV || this.world.y(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
     }
 
-    public boolean aK() {
+    public boolean aT() {
         return this.bV;
     }
 
-    public boolean i_() {
+    public boolean h_() {
         return this.world.a(this.boundingBox.grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.0010D, 0.0010D, 0.0010D), Material.WATER, this);
     }
 
@@ -756,7 +756,7 @@ public abstract class Entity {
         return 0.0F;
     }
 
-    public boolean aL() {
+    public boolean aU() {
         return this.world.a(this.boundingBox.grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
     }
 
@@ -779,15 +779,15 @@ public abstract class Entity {
         }
     }
 
-    public float a(float f) {
+    public float b(float f) {
         int i = MathHelper.floor(this.locX);
         int j = MathHelper.floor(this.locZ);
 
-        if (this.world.isLoaded(i, this.world.height / 2, j)) {
+        if (this.world.isLoaded(i, 0, j)) {
             double d0 = (this.boundingBox.e - this.boundingBox.b) * 0.66D;
             int k = MathHelper.floor(this.locY - (double) this.height + d0);
 
-            return this.world.m(i, k, j);
+            return this.world.p(i, k, j);
         } else {
             return 0.0F;
         }
@@ -834,7 +834,7 @@ public abstract class Entity {
         this.setPosition(this.locX, this.locY, this.locZ);
     }
 
-    public float h(Entity entity) {
+    public float i(Entity entity) {
         float f = (float) (this.locX - entity.locX);
         float f1 = (float) (this.locY - entity.locY);
         float f2 = (float) (this.locZ - entity.locZ);
@@ -858,7 +858,7 @@ public abstract class Entity {
         return (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
     }
 
-    public double i(Entity entity) {
+    public double j(Entity entity) {
         double d0 = this.locX - entity.locX;
         double d1 = this.locY - entity.locY;
         double d2 = this.locZ - entity.locZ;
@@ -903,12 +903,16 @@ public abstract class Entity {
         this.ce = true;
     }
 
-    protected void aM() {
+    protected void aV() {
         this.velocityChanged = true;
     }
 
     public boolean damageEntity(DamageSource damagesource, int i) {
-        this.aM();
+        this.aV();
+        return false;
+    }
+
+    public boolean o_() {
         return false;
     }
 
@@ -916,14 +920,10 @@ public abstract class Entity {
         return false;
     }
 
-    public boolean f_() {
-        return false;
-    }
-
     public void b(Entity entity, int i) {}
 
     public boolean c(NBTTagCompound nbttagcompound) {
-        String s = this.aN();
+        String s = this.aW();
 
         if (!this.dead && s != null) {
             nbttagcompound.setString("id", s);
@@ -1048,7 +1048,7 @@ public abstract class Entity {
         // CraftBukkit end
     }
 
-    protected final String aN() {
+    protected final String aW() {
         return EntityTypes.b(this);
     }
 
@@ -1125,20 +1125,20 @@ public abstract class Entity {
         return false;
     }
 
-    public AxisAlignedBB a_(Entity entity) {
+    public AxisAlignedBB b_(Entity entity) {
         return null;
     }
 
-    public void N() {
+    public void Q() {
         if (this.vehicle.dead) {
             this.vehicle = null;
         } else {
             this.motX = 0.0D;
             this.motY = 0.0D;
             this.motZ = 0.0D;
-            this.y_();
+            this.G_();
             if (this.vehicle != null) {
-                this.vehicle.i();
+                this.vehicle.i_();
                 this.f += (double) (this.vehicle.yaw - this.vehicle.lastYaw);
 
                 for (this.e += (double) (this.vehicle.pitch - this.vehicle.lastPitch); this.f >= 180.0D; this.f -= 360.0D) {
@@ -1185,15 +1185,15 @@ public abstract class Entity {
         }
     }
 
-    public void i() {
-        this.passenger.setPosition(this.locX, this.locY + this.q() + this.passenger.S(), this.locZ);
+    public void i_() {
+        this.passenger.setPosition(this.locX, this.locY + this.x_() + this.passenger.V(), this.locZ);
     }
 
-    public double S() {
+    public double V() {
         return (double) this.height;
     }
 
-    public double q() {
+    public double x_() {
         return (double) this.length * 0.75D;
     }
 
@@ -1274,22 +1274,22 @@ public abstract class Entity {
         return 0.1F;
     }
 
-    public Vec3D aA() {
+    public Vec3D aI() {
         return null;
     }
 
-    public void Y() {}
+    public void ac() {}
 
     public ItemStack[] getEquipment() {
         return null;
     }
 
     public boolean isBurning() {
-        return this.fireTicks > 0 || this.k(0);
+        return this.fireTicks > 0 || this.j(0);
     }
 
     public boolean isSneaking() {
-        return this.k(1);
+        return this.j(1);
     }
 
     public void setSneak(boolean flag) {
@@ -1297,18 +1297,18 @@ public abstract class Entity {
     }
 
     public boolean isSprinting() {
-        return this.k(3);
+        return this.j(3);
     }
 
     public void setSprinting(boolean flag) {
         this.a(3, flag);
     }
 
-    public void h(boolean flag) {
+    public void i(boolean flag) {
         this.a(4, flag);
     }
 
-    protected boolean k(int i) {
+    protected boolean j(int i) {
         return (this.datawatcher.getByte(0) & 1 << i) != 0;
     }
 
@@ -1367,7 +1367,7 @@ public abstract class Entity {
         }
     }
 
-    public void a(EntityLiving entityliving) {}
+    public void c(EntityLiving entityliving) {}
 
     protected boolean g(double d0, double d1, double d2) {
         int i = MathHelper.floor(d0);
@@ -1449,7 +1449,7 @@ public abstract class Entity {
         }
     }
 
-    public void s() {
+    public void u() {
         this.bC = true;
         this.fallDistance = 0.0F;
     }
@@ -1464,11 +1464,19 @@ public abstract class Entity {
         return LocaleI18n.get("entity." + s + ".name");
     }
 
-    public Entity[] aR() {
+    public Entity[] ba() {
         return null;
     }
 
-    public boolean a(Entity entity) {
+    public boolean a_(Entity entity) {
         return this == entity;
     }
+
+    public float aq() {
+        return 0.0F;
+    }
+
+    public boolean k_() {
+        return true;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/EntityAgeable.java b/src/main/java/net/minecraft/server/EntityAgeable.java
new file mode 100644
index 0000000000..fd5b948ccb
--- /dev/null
+++ b/src/main/java/net/minecraft/server/EntityAgeable.java
@@ -0,0 +1,52 @@
+package net.minecraft.server;
+
+public abstract class EntityAgeable extends EntityCreature {
+    public boolean ageLocked = false; // CraftBukkit
+
+    public EntityAgeable(World world) {
+        super(world);
+    }
+
+    protected void b() {
+        super.b();
+        this.datawatcher.a(12, new Integer(0));
+    }
+
+    public int getAge() {
+        return this.datawatcher.getInt(12);
+    }
+
+    public void setAge(int i) {
+        this.datawatcher.watch(12, Integer.valueOf(i));
+    }
+
+    public void b(NBTTagCompound nbttagcompound) {
+        super.b(nbttagcompound);
+        nbttagcompound.setInt("Age", this.getAge());
+        nbttagcompound.setBoolean("AgeLocked", this.ageLocked); // CraftBukkit
+    }
+
+    public void a(NBTTagCompound nbttagcompound) {
+        super.a(nbttagcompound);
+        this.setAge(nbttagcompound.getInt("Age"));
+        this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); // CraftBukkit
+    }
+
+    public void e() {
+        super.e();
+        int i = this.getAge();
+
+        if (ageLocked) return; // CraftBukkit
+        if (i < 0) {
+            ++i;
+            this.setAge(i);
+        } else if (i > 0) {
+            --i;
+            this.setAge(i);
+        }
+    }
+
+    public boolean isBaby() {
+        return this.getAge() < 0;
+    }
+}
diff --git a/src/main/java/net/minecraft/server/EntityAnimal.java b/src/main/java/net/minecraft/server/EntityAnimal.java
deleted file mode 100644
index 80e416ecdb..0000000000
--- a/src/main/java/net/minecraft/server/EntityAnimal.java
+++ /dev/null
@@ -1,258 +0,0 @@
-package net.minecraft.server;
-
-import java.util.List;
-
-public abstract class EntityAnimal extends EntityCreature implements IAnimal {
-
-    private int love;
-    private int b = 0;
-    public boolean ageLocked = false; // CraftBukkit
-
-    public EntityAnimal(World world) {
-        super(world);
-    }
-
-    protected void b() {
-        super.b();
-        this.datawatcher.a(12, new Integer(0));
-    }
-
-    public int getAge() {
-        return this.datawatcher.getInt(12);
-    }
-
-    public void setAge(int i) {
-        this.datawatcher.watch(12, Integer.valueOf(i));
-    }
-
-    public void d() {
-        super.d();
-        int i = this.getAge();
-
-        if (!ageLocked) { // CraftBukkit
-        if (i < 0) {
-            ++i;
-            this.setAge(i);
-        } else if (i > 0) {
-            --i;
-            this.setAge(i);
-        }
-        } // CraftBukkit
-
-        if (this.love > 0) {
-            --this.love;
-            String s = "heart";
-
-            if (this.love % 10 == 0) {
-                double d0 = this.random.nextGaussian() * 0.02D;
-                double d1 = this.random.nextGaussian() * 0.02D;
-                double d2 = this.random.nextGaussian() * 0.02D;
-
-                this.world.a(s, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2);
-            }
-        } else {
-            this.b = 0;
-        }
-    }
-
-    protected void a(Entity entity, float f) {
-        if (entity instanceof EntityHuman) {
-            if (f < 3.0F) {
-                double d0 = entity.locX - this.locX;
-                double d1 = entity.locZ - this.locZ;
-
-                this.yaw = (float) (Math.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
-                this.e = true;
-            }
-
-            EntityHuman entityhuman = (EntityHuman) entity;
-
-            if (entityhuman.Q() == null || !this.a(entityhuman.Q())) {
-                this.target = null;
-            }
-        } else if (entity instanceof EntityAnimal) {
-            EntityAnimal entityanimal = (EntityAnimal) entity;
-
-            if (this.getAge() > 0 && entityanimal.getAge() < 0) {
-                if ((double) f < 2.5D) {
-                    this.e = true;
-                }
-            } else if (this.love > 0 && entityanimal.love > 0) {
-                if (entityanimal.target == null) {
-                    entityanimal.target = this;
-                }
-
-                if (entityanimal.target == this && (double) f < 3.5D) {
-                    ++entityanimal.love;
-                    ++this.love;
-                    ++this.b;
-                    if (this.b % 4 == 0) {
-                        this.world.a("heart", this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, 0.0D, 0.0D, 0.0D);
-                    }
-
-                    if (this.b == 60) {
-                        this.b((EntityAnimal) entity);
-                    }
-                } else {
-                    this.b = 0;
-                }
-            } else {
-                this.b = 0;
-                this.target = null;
-            }
-        }
-    }
-
-    private void b(EntityAnimal entityanimal) {
-        EntityAnimal entityanimal1 = this.createChild(entityanimal);
-
-        if (entityanimal1 != null) {
-            this.setAge(6000);
-            entityanimal.setAge(6000);
-            this.love = 0;
-            this.b = 0;
-            this.target = null;
-            entityanimal.target = null;
-            entityanimal.b = 0;
-            entityanimal.love = 0;
-            entityanimal1.setAge(-24000);
-            entityanimal1.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch);
-
-            for (int i = 0; i < 7; ++i) {
-                double d0 = this.random.nextGaussian() * 0.02D;
-                double d1 = this.random.nextGaussian() * 0.02D;
-                double d2 = this.random.nextGaussian() * 0.02D;
-
-                this.world.a("heart", this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2);
-            }
-
-            this.world.addEntity(entityanimal1);
-        }
-    }
-
-    protected abstract EntityAnimal createChild(EntityAnimal entityanimal);
-
-    protected void b(Entity entity, float f) {}
-
-    public boolean damageEntity(DamageSource damagesource, int i) {
-        this.f = 60;
-        this.target = null;
-        this.love = 0;
-        return super.damageEntity(damagesource, i);
-    }
-
-    public float a(int i, int j, int k) {
-        return this.world.getTypeId(i, j - 1, k) == Block.GRASS.id ? 10.0F : this.world.m(i, j, k) - 0.5F;
-    }
-
-    public void b(NBTTagCompound nbttagcompound) {
-        super.b(nbttagcompound);
-        nbttagcompound.setInt("Age", this.getAge());
-        nbttagcompound.setInt("InLove", this.love);
-        nbttagcompound.setBoolean("AgeLocked", this.ageLocked); // CraftBukkit
-    }
-
-    public void a(NBTTagCompound nbttagcompound) {
-        super.a(nbttagcompound);
-        this.setAge(nbttagcompound.getInt("Age"));
-        this.love = nbttagcompound.getInt("InLove");
-        this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); // CraftBukkit
-    }
-
-    protected Entity findTarget() {
-        if (this.f > 0) {
-            return null;
-        } else {
-            float f = 8.0F;
-            List list;
-            int i;
-            EntityAnimal entityanimal;
-
-            if (this.love > 0) {
-                list = this.world.a(this.getClass(), this.boundingBox.grow((double) f, (double) f, (double) f));
-
-                for (i = 0; i < list.size(); ++i) {
-                    entityanimal = (EntityAnimal) list.get(i);
-                    if (entityanimal != this && entityanimal.love > 0) {
-                        return entityanimal;
-                    }
-                }
-            } else if (this.getAge() == 0) {
-                list = this.world.a(EntityHuman.class, this.boundingBox.grow((double) f, (double) f, (double) f));
-
-                for (i = 0; i < list.size(); ++i) {
-                    EntityHuman entityhuman = (EntityHuman) list.get(i);
-
-                    if (entityhuman.Q() != null && this.a(entityhuman.Q())) {
-                        return entityhuman;
-                    }
-                }
-            } else if (this.getAge() > 0) {
-                list = this.world.a(this.getClass(), this.boundingBox.grow((double) f, (double) f, (double) f));
-
-                for (i = 0; i < list.size(); ++i) {
-                    entityanimal = (EntityAnimal) list.get(i);
-                    if (entityanimal != this && entityanimal.getAge() < 0) {
-                        return entityanimal;
-                    }
-                }
-            }
-
-            return null;
-        }
-    }
-
-    public boolean canSpawn() {
-        int i = MathHelper.floor(this.locX);
-        int j = MathHelper.floor(this.boundingBox.b);
-        int k = MathHelper.floor(this.locZ);
-
-        return this.world.getTypeId(i, j - 1, k) == Block.GRASS.id && this.world.k(i, j, k) > 8 && super.canSpawn();
-    }
-
-    public int h() {
-        return 120;
-    }
-
-    protected boolean d_() {
-        return false;
-    }
-
-    protected int getExpValue(EntityHuman entityhuman) {
-        return 1 + this.world.random.nextInt(3);
-    }
-
-    protected boolean a(ItemStack itemstack) {
-        return itemstack.id == Item.WHEAT.id;
-    }
-
-    public boolean b(EntityHuman entityhuman) {
-        ItemStack itemstack = entityhuman.inventory.getItemInHand();
-
-        if (itemstack != null && this.a(itemstack) && this.getAge() == 0) {
-            --itemstack.count;
-            if (itemstack.count <= 0) {
-                entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
-            }
-
-            this.love = 600;
-            this.target = null;
-
-            for (int i = 0; i < 7; ++i) {
-                double d0 = this.random.nextGaussian() * 0.02D;
-                double d1 = this.random.nextGaussian() * 0.02D;
-                double d2 = this.random.nextGaussian() * 0.02D;
-
-                this.world.a("heart", this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2);
-            }
-
-            return true;
-        } else {
-            return super.b(entityhuman);
-        }
-    }
-
-    public boolean isBaby() {
-        return this.getAge() < 0;
-    }
-}
diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java
index 70a352f8b4..d258e0fab6 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -39,6 +39,30 @@ public class EntityArrow extends Entity {
         this.height = 0.0F;
     }
 
+    public EntityArrow(World world, EntityLiving entityliving, EntityLiving entityliving1, float f, float f1) {
+        super(world);
+        this.shooter = entityliving;
+        this.fromPlayer = entityliving instanceof EntityHuman;
+        this.locY = entityliving.locY + (double) entityliving.getHeadHeight() - 0.10000000149011612D;
+        double d0 = entityliving1.locX - entityliving.locX;
+        double d1 = entityliving1.locY + (double) entityliving1.getHeadHeight() - 0.699999988079071D - this.locY;
+        double d2 = entityliving1.locZ - entityliving.locZ;
+        double d3 = (double) MathHelper.sqrt(d0 * d0 + d2 * d2);
+
+        if (d3 >= 1.0E-7D) {
+            float f2 = (float) (Math.atan2(d2, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
+            float f3 = (float) (-(Math.atan2(d1, d3) * 180.0D / 3.1415927410125732D));
+            double d4 = d0 / d3;
+            double d5 = d2 / d3;
+
+            this.setPositionRotation(entityliving.locX + d4, this.locY, entityliving.locZ + d5, f2, f3);
+            this.height = 0.0F;
+            float f4 = (float) d3 * 0.2F;
+
+            this.shoot(d0, d1 + (double) f4, d2, f, f1);
+        }
+    }
+
     public EntityArrow(World world, EntityLiving entityliving, float f) {
         super(world);
         this.shooter = entityliving;
@@ -80,8 +104,8 @@ public class EntityArrow extends Entity {
         this.k = 0;
     }
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         if (this.lastPitch == 0.0F && this.lastYaw == 0.0F) {
             float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ);
 
@@ -143,7 +167,7 @@ public class EntityArrow extends Entity {
             for (k = 0; k < list.size(); ++k) {
                 Entity entity1 = (Entity) list.get(k);
 
-                if (entity1.e_() && (entity1 != this.shooter || this.l >= 5)) {
+                if (entity1.o_() && (entity1 != this.shooter || this.l >= 5)) {
                     f1 = 0.3F;
                     AxisAlignedBB axisalignedbb1 = entity1.boundingBox.grow((double) f1, (double) f1, (double) f1);
                     MovingObjectPosition movingobjectposition1 = axisalignedbb1.a(vec3d, vec3d1);
@@ -200,7 +224,7 @@ public class EntityArrow extends Entity {
                     // CraftBukkit - entity.damageEntity -> event function
                     if (org.bukkit.craftbukkit.event.CraftEventFactory.handleProjectileEvent(projectile, entity, damagesource, l)) {
                         if (movingobjectposition.entity instanceof EntityLiving) {
-                            ++((EntityLiving) movingobjectposition.entity).aJ;
+                            ++((EntityLiving) movingobjectposition.entity).aI;
                             if (this.n > 0) {
                                 float f3 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ);
 
@@ -273,7 +297,7 @@ public class EntityArrow extends Entity {
             float f4 = 0.99F;
 
             f1 = 0.05F;
-            if (this.aK()) {
+            if (this.aT()) {
                 for (int i1 = 0; i1 < 4; ++i1) {
                     float f5 = 0.25F;
 
@@ -345,11 +369,15 @@ public class EntityArrow extends Entity {
         this.damage = d0;
     }
 
-    public double j() {
+    public double k() {
         return this.damage;
     }
 
     public void b(int i) {
         this.n = i;
     }
+
+    public boolean k_() {
+        return false;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/EntityBlaze.java b/src/main/java/net/minecraft/server/EntityBlaze.java
index 97956c2706..b43460e9c2 100644
--- a/src/main/java/net/minecraft/server/EntityBlaze.java
+++ b/src/main/java/net/minecraft/server/EntityBlaze.java
@@ -26,15 +26,15 @@ public class EntityBlaze extends EntityMonster {
         this.datawatcher.a(16, new Byte((byte) 0));
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.blaze.breathe";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.blaze.hit";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.blaze.death";
     }
 
@@ -46,13 +46,13 @@ public class EntityBlaze extends EntityMonster {
         super.die(damagesource);
     }
 
-    public float a(float f) {
+    public float b(float f) {
         return 1.0F;
     }
 
-    public void d() {
+    public void e() {
         if (!this.world.isStatic) {
-            if (this.aJ()) {
+            if (this.aS()) {
                 this.damageEntity(DamageSource.DROWN, 1);
             }
 
@@ -62,7 +62,7 @@ public class EntityBlaze extends EntityMonster {
                 this.a = 0.5F + (float) this.random.nextGaussian() * 3.0F;
             }
 
-            if (this.F() != null && this.F().locY + (double) this.F().getHeadHeight() > this.locY + (double) this.getHeadHeight() + (double) this.a) {
+            if (this.H() != null && this.H().locY + (double) this.H().getHeadHeight() > this.locY + (double) this.getHeadHeight() + (double) this.a) {
                 this.motY += (0.30000001192092896D - this.motY) * 0.30000001192092896D;
             }
         }
@@ -79,13 +79,13 @@ public class EntityBlaze extends EntityMonster {
             this.world.a("largesmoke", this.locX + (this.random.nextDouble() - 0.5D) * (double) this.width, this.locY + this.random.nextDouble() * (double) this.length, this.locZ + (this.random.nextDouble() - 0.5D) * (double) this.width, 0.0D, 0.0D, 0.0D);
         }
 
-        super.d();
+        super.e();
     }
 
     protected void a(Entity entity, float f) {
         if (this.attackTicks <= 0 && f < 2.0F && entity.boundingBox.e > this.boundingBox.b && entity.boundingBox.b < this.boundingBox.e) {
             this.attackTicks = 20;
-            this.d(entity);
+            this.a(entity);
         } else if (f < 30.0F) {
             double d0 = entity.locX - this.locX;
             double d1 = entity.boundingBox.b + (double) (entity.length / 2.0F) - (this.locY + (double) (this.length / 2.0F));
@@ -123,7 +123,7 @@ public class EntityBlaze extends EntityMonster {
         }
     }
 
-    protected void b(float f) {}
+    protected void a(float f) {}
 
     public void b(NBTTagCompound nbttagcompound) {
         super.b(nbttagcompound);
@@ -138,7 +138,7 @@ public class EntityBlaze extends EntityMonster {
     }
 
     public boolean isBurning() {
-        return this.B();
+        return this.A();
     }
 
     protected void dropDeathLoot(boolean flag, int i) {
@@ -156,7 +156,7 @@ public class EntityBlaze extends EntityMonster {
         }
     }
 
-    public boolean B() {
+    public boolean A() {
         return (this.datawatcher.getByte(16) & 1) != 0;
     }
 
@@ -172,7 +172,7 @@ public class EntityBlaze extends EntityMonster {
         this.datawatcher.watch(16, Byte.valueOf(b0));
     }
 
-    protected boolean z() {
+    protected boolean D() {
         return true;
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityBoat.java b/src/main/java/net/minecraft/server/EntityBoat.java
index 69d5f7cb8f..e447f4c9f2 100644
--- a/src/main/java/net/minecraft/server/EntityBoat.java
+++ b/src/main/java/net/minecraft/server/EntityBoat.java
@@ -61,15 +61,15 @@ public class EntityBoat extends Entity {
         this.datawatcher.a(19, new Integer(0));
     }
 
-    public AxisAlignedBB a_(Entity entity) {
+    public AxisAlignedBB b_(Entity entity) {
         return entity.boundingBox;
     }
 
-    public AxisAlignedBB h_() {
+    public AxisAlignedBB h() {
         return this.boundingBox;
     }
 
-    public boolean f_() {
+    public boolean e_() {
         return true;
     }
 
@@ -86,7 +86,7 @@ public class EntityBoat extends Entity {
         this.world.getServer().getPluginManager().callEvent(new VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit
     }
 
-    public double q() {
+    public double x_() {
         return (double) this.length * 0.0D - 0.30000001192092896D;
     }
 
@@ -105,10 +105,10 @@ public class EntityBoat extends Entity {
             // i = event.getDamage(); // TODO Why don't we do this?
             // CraftBukkit end
 
-            this.d(-this.l());
+            this.d(-this.m());
             this.c(10);
             this.setDamage(this.getDamage() + i * 10);
-            this.aM();
+            this.aV();
             if (this.getDamage() > 40) {
                 // CraftBukkit start
                 VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker);
@@ -143,11 +143,11 @@ public class EntityBoat extends Entity {
         }
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return !this.dead;
     }
 
-    public void y_() {
+    public void G_() {
         // CraftBukkit start
         double prevX = this.locX;
         double prevY = this.locY;
@@ -156,9 +156,9 @@ public class EntityBoat extends Entity {
         float prevPitch = this.pitch;
         // CraftBukkit end
 
-        super.y_();
-        if (this.k() > 0) {
-            this.c(this.k() - 1);
+        super.G_();
+        if (this.l() > 0) {
+            this.c(this.l() - 1);
         }
 
         if (this.getDamage() > 0) {
@@ -379,7 +379,7 @@ public class EntityBoat extends Entity {
                 for (l = 0; l < list.size(); ++l) {
                     Entity entity = (Entity) list.get(l);
 
-                    if (entity != this.passenger && entity.f_() && entity instanceof EntityBoat) {
+                    if (entity != this.passenger && entity.e_() && entity instanceof EntityBoat) {
                         entity.collide(this);
                     }
                 }
@@ -402,12 +402,12 @@ public class EntityBoat extends Entity {
         }
     }
 
-    public void i() {
+    public void i_() {
         if (this.passenger != null) {
             double d0 = Math.cos((double) this.yaw * 3.141592653589793D / 180.0D) * 0.4D;
             double d1 = Math.sin((double) this.yaw * 3.141592653589793D / 180.0D) * 0.4D;
 
-            this.passenger.setPosition(this.locX + d0, this.locY + this.q() + this.passenger.S(), this.locZ + d1);
+            this.passenger.setPosition(this.locX + d0, this.locY + this.x_() + this.passenger.V(), this.locZ + d1);
         }
     }
 
@@ -439,7 +439,7 @@ public class EntityBoat extends Entity {
         this.datawatcher.watch(17, Integer.valueOf(i));
     }
 
-    public int k() {
+    public int l() {
         return this.datawatcher.getInt(17);
     }
 
@@ -447,7 +447,7 @@ public class EntityBoat extends Entity {
         this.datawatcher.watch(18, Integer.valueOf(i));
     }
 
-    public int l() {
+    public int m() {
         return this.datawatcher.getInt(18);
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java
index c6862e1d35..323d6ddcde 100644
--- a/src/main/java/net/minecraft/server/EntityChicken.java
+++ b/src/main/java/net/minecraft/server/EntityChicken.java
@@ -20,14 +20,28 @@ public class EntityChicken extends EntityAnimal {
         this.texture = "/mob/chicken.png";
         this.b(0.3F, 0.7F);
         this.j = this.random.nextInt(6000) + 6000;
+        float f = 0.25F;
+
+        this.goalSelector.a(0, new PathfinderGoalFloat(this));
+        this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.38F));
+        this.goalSelector.a(2, new PathfinderGoalBreed(this, f));
+        this.goalSelector.a(3, new PathfinderGoalTempt(this, 0.25F, Item.WHEAT.id, false));
+        this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 0.28F));
+        this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, f));
+        this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
+        this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
+    }
+
+    public boolean c_() {
+        return true;
     }
 
     public int getMaxHealth() {
         return 4;
     }
 
-    public void d() {
-        super.d();
+    public void e() {
+        super.e();
         this.h = this.b;
         this.g = this.c;
         this.c = (float) ((double) this.c + (double) (this.onGround ? -1 : 4) * 0.3D);
@@ -56,7 +70,7 @@ public class EntityChicken extends EntityAnimal {
         }
     }
 
-    protected void b(float f) {}
+    protected void a(float f) {}
 
     public void b(NBTTagCompound nbttagcompound) {
         super.b(nbttagcompound);
@@ -66,15 +80,15 @@ public class EntityChicken extends EntityAnimal {
         super.a(nbttagcompound);
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.chicken";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.chickenhurt";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.chickenhurt";
     }
 
@@ -101,7 +115,7 @@ public class EntityChicken extends EntityAnimal {
         // CraftBukkit end
     }
 
-    protected EntityAnimal createChild(EntityAnimal entityanimal) {
+    public EntityAnimal createChild(EntityAnimal entityanimal) {
         return new EntityChicken(this.world);
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java
index 505d42a9ae..1b27b97370 100644
--- a/src/main/java/net/minecraft/server/EntityCow.java
+++ b/src/main/java/net/minecraft/server/EntityCow.java
@@ -15,6 +15,19 @@ public class EntityCow extends EntityAnimal {
         super(world);
         this.texture = "/mob/cow.png";
         this.b(0.9F, 1.3F);
+        this.ak().a(true);
+        this.goalSelector.a(0, new PathfinderGoalFloat(this));
+        this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.38F));
+        this.goalSelector.a(2, new PathfinderGoalBreed(this, 0.2F));
+        this.goalSelector.a(3, new PathfinderGoalTempt(this, 0.25F, Item.WHEAT.id, false));
+        this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 0.25F));
+        this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 0.2F));
+        this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
+        this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
+    }
+
+    public boolean c_() {
+        return true;
     }
 
     public int getMaxHealth() {
@@ -29,19 +42,19 @@ public class EntityCow extends EntityAnimal {
         super.a(nbttagcompound);
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.cow";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.cowhurt";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.cowhurt";
     }
 
-    protected float o() {
+    protected float p() {
         return 0.4F;
     }
 
@@ -89,7 +102,7 @@ public class EntityCow extends EntityAnimal {
         }
     }
 
-    protected EntityAnimal createChild(EntityAnimal entityanimal) {
+    public EntityAnimal createChild(EntityAnimal entityanimal) {
         return new EntityCow(this.world);
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java
index b632cedcab..b865cbd5e6 100644
--- a/src/main/java/net/minecraft/server/EntityCreature.java
+++ b/src/main/java/net/minecraft/server/EntityCreature.java
@@ -17,17 +17,17 @@ public abstract class EntityCreature extends EntityLiving {
         super(world);
     }
 
-    protected boolean v() {
+    protected boolean E() {
         return false;
     }
 
-    protected void m_() {
+    protected void d_() {
         // MethodProfiler.a("ai"); // CraftBukkit - not in production code
         if (this.f > 0) {
             --this.f;
         }
 
-        this.e = this.v();
+        this.e = this.E();
         float f = 16.0F;
 
         if (this.target == null) {
@@ -48,7 +48,7 @@ public abstract class EntityCreature extends EntityLiving {
             // CraftBukkit end
 
             if (this.target != null) {
-                this.pathEntity = this.world.findPath(this, this.target, f);
+                this.pathEntity = this.world.findPath(this, this.target, f, true, false, false, true);
             }
         } else if (!this.target.isAlive()) {
             // CraftBukkit start
@@ -64,9 +64,9 @@ public abstract class EntityCreature extends EntityLiving {
             }
             // CraftBukkit end
         } else {
-            float f1 = this.target.h(this);
+            float f1 = this.target.i(this);
 
-            if (this.g(this.target)) {
+            if (this.h(this.target)) {
                 this.a(this.target, f1);
             } else {
                 this.b(this.target, f1);
@@ -75,19 +75,19 @@ public abstract class EntityCreature extends EntityLiving {
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
         if (!this.e && this.target != null && (this.pathEntity == null || this.random.nextInt(20) == 0)) {
-            this.pathEntity = this.world.findPath(this, this.target, f);
+            this.pathEntity = this.world.findPath(this, this.target, f, true, false, false, true);
         } else if (!this.e && (this.pathEntity == null && this.random.nextInt(180) == 0 || this.random.nextInt(120) == 0 || this.f > 0) && this.aV < 100) {
-            this.D();
+            this.F();
         }
 
         int i = MathHelper.floor(this.boundingBox.b + 0.5D);
-        boolean flag = this.aK();
-        boolean flag1 = this.aL();
+        boolean flag = this.aT();
+        boolean flag1 = this.aU();
 
         this.pitch = 0.0F;
         if (this.pathEntity != null && this.random.nextInt(100) != 0) {
             // MethodProfiler.a("followpath"); // CraftBukkit - not in production code
-            Vec3D vec3d = this.pathEntity.a(this);
+            Vec3D vec3d = this.pathEntity.a((Entity) this);
             double d0 = (double) (this.width * 2.0F);
 
             while (vec3d != null && vec3d.d(this.locX, vec3d.b, this.locZ) < d0 * d0) {
@@ -96,7 +96,7 @@ public abstract class EntityCreature extends EntityLiving {
                     vec3d = null;
                     this.pathEntity = null;
                 } else {
-                    vec3d = this.pathEntity.a(this);
+                    vec3d = this.pathEntity.a((Entity) this);
                 }
             }
 
@@ -146,7 +146,7 @@ public abstract class EntityCreature extends EntityLiving {
                 this.a(this.target, 30.0F, 30.0F);
             }
 
-            if (this.positionChanged && !this.E()) {
+            if (this.positionChanged && !this.G()) {
                 this.aZ = true;
             }
 
@@ -156,12 +156,12 @@ public abstract class EntityCreature extends EntityLiving {
 
             // MethodProfiler.a(); // CraftBukkit - not in production code
         } else {
-            super.m_();
+            super.d_();
             this.pathEntity = null;
         }
     }
 
-    protected void D() {
+    protected void F() {
         // MethodProfiler.a("stroll"); // CraftBukkit - not in production code
         boolean flag = false;
         int i = -1;
@@ -185,7 +185,7 @@ public abstract class EntityCreature extends EntityLiving {
         }
 
         if (flag) {
-            this.pathEntity = this.world.a(this, i, j, k, 10.0F);
+            this.pathEntity = this.world.a(this, i, j, k, 10.0F, true, false, false, true);
         }
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
@@ -211,7 +211,7 @@ public abstract class EntityCreature extends EntityLiving {
         return super.canSpawn() && this.a(i, j, k) >= 0.0F;
     }
 
-    public boolean E() {
+    public boolean G() {
         return this.pathEntity != null;
     }
 
@@ -219,7 +219,7 @@ public abstract class EntityCreature extends EntityLiving {
         this.pathEntity = pathentity;
     }
 
-    public Entity F() {
+    public Entity H() {
         return this.target;
     }
 
@@ -227,13 +227,17 @@ public abstract class EntityCreature extends EntityLiving {
         this.target = entity;
     }
 
-    protected float G() {
-        float f = super.G();
+    protected float D_() {
+        if (this.c_()) {
+            return 1.0F;
+        } else {
+            float f = super.D_();
 
-        if (this.f > 0) {
-            f *= 2.0F;
+            if (this.f > 0) {
+                f *= 2.0F;
+            }
+
+            return f;
         }
-
-        return f;
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java
index 9ecbaca42d..00f92a0153 100644
--- a/src/main/java/net/minecraft/server/EntityCreeper.java
+++ b/src/main/java/net/minecraft/server/EntityCreeper.java
@@ -10,6 +10,19 @@ public class EntityCreeper extends EntityMonster {
     public EntityCreeper(World world) {
         super(world);
         this.texture = "/mob/creeper.png";
+        this.goalSelector.a(1, new PathfinderGoalFloat(this));
+        this.goalSelector.a(2, new PathfinderGoalSwell(this));
+        this.goalSelector.a(3, new PathfinderGoalAvoidPlayer(this, EntityOcelot.class, 6.0F, 0.25F, 0.3F));
+        this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 0.25F, false));
+        this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 0.2F));
+        this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
+        this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this));
+        this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, false));
+        this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false));
+    }
+
+    public boolean c_() {
+        return true;
     }
 
     public int getMaxHealth() {
@@ -34,22 +47,10 @@ public class EntityCreeper extends EntityMonster {
         this.datawatcher.watch(17, Byte.valueOf((byte) (nbttagcompound.getBoolean("powered") ? 1 : 0)));
     }
 
-    protected void b(Entity entity, float f) {
-        if (!this.world.isStatic) {
-            if (this.fuseTicks > 0) {
-                this.b(-1);
-                --this.fuseTicks;
-                if (this.fuseTicks < 0) {
-                    this.fuseTicks = 0;
-                }
-            }
-        }
-    }
-
-    public void y_() {
-        this.b = this.fuseTicks;
-        if (this.world.isStatic) {
-            int i = this.B();
+    public void G_() {
+        if (this.isAlive()) {
+            this.b = this.fuseTicks;
+            int i = this.A();
 
             if (i > 0 && this.fuseTicks == 0) {
                 this.world.makeSound(this, "random.fuse", 1.0F, 0.5F);
@@ -62,24 +63,30 @@ public class EntityCreeper extends EntityMonster {
 
             if (this.fuseTicks >= 30) {
                 this.fuseTicks = 30;
+                // CraftBukkit start
+                float radius = this.isPowered() ? 6.0F : 3.0F;
+
+                ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), radius, false);
+                this.world.getServer().getPluginManager().callEvent(event);
+
+                if (!event.isCancelled()) {
+                    this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire());
+                    this.die();
+                } else {
+                    this.fuseTicks = 0;
+                }
+                // CraftBukkit end
             }
         }
 
-        super.y_();
-        if (this.target == null && this.fuseTicks > 0) {
-            this.b(-1);
-            --this.fuseTicks;
-            if (this.fuseTicks < 0) {
-                this.fuseTicks = 0;
-            }
-        }
+        super.G_();
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.creeper";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.creeperdeath";
     }
 
@@ -90,42 +97,8 @@ public class EntityCreeper extends EntityMonster {
         }
     }
 
-    protected void a(Entity entity, float f) {
-        if (!this.world.isStatic) {
-            int i = this.B();
-
-            if ((i > 0 || f >= 3.0F) && (i <= 0 || f >= 7.0F)) {
-                this.b(-1);
-                --this.fuseTicks;
-                if (this.fuseTicks < 0) {
-                    this.fuseTicks = 0;
-                }
-            } else {
-                if (this.fuseTicks == 0) {
-                    this.world.makeSound(this, "random.fuse", 1.0F, 0.5F);
-                }
-
-                this.b(1);
-                ++this.fuseTicks;
-                if (this.fuseTicks >= 30) {
-                    // CraftBukkit start
-                    float radius = this.isPowered() ? 6.0F : 3.0F;
-
-                    ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), radius, false);
-                    this.world.getServer().getPluginManager().callEvent(event);
-
-                    if (!event.isCancelled()) {
-                        this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire());
-                        this.die();
-                    } else {
-                        this.fuseTicks = 0;
-                    }
-                    // CraftBukkit end
-                }
-
-                this.e = true;
-            }
-        }
+    public boolean a(Entity entity) {
+        return true;
     }
 
     public boolean isPowered() {
@@ -136,11 +109,11 @@ public class EntityCreeper extends EntityMonster {
         return Item.SULPHUR.id;
     }
 
-    private int B() {
+    public int A() {
         return this.datawatcher.getByte(16);
     }
 
-    private void b(int i) {
+    public void c(int i) {
         this.datawatcher.watch(16, Byte.valueOf((byte) i));
     }
 
diff --git a/src/main/java/net/minecraft/server/EntityEnderCrystal.java b/src/main/java/net/minecraft/server/EntityEnderCrystal.java
index ea4565c73d..5079d2295d 100644
--- a/src/main/java/net/minecraft/server/EntityEnderCrystal.java
+++ b/src/main/java/net/minecraft/server/EntityEnderCrystal.java
@@ -22,7 +22,7 @@ public class EntityEnderCrystal extends Entity {
         this.datawatcher.a(8, Integer.valueOf(this.b));
     }
 
-    public void y_() {
+    public void G_() {
         this.lastX = this.locX;
         this.lastY = this.locY;
         this.lastZ = this.locZ;
@@ -41,7 +41,7 @@ public class EntityEnderCrystal extends Entity {
 
     protected void a(NBTTagCompound nbttagcompound) {}
 
-    public boolean e_() {
+    public boolean o_() {
         return true;
     }
 
diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index 4f00f297df..c46d02d60d 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -88,7 +88,7 @@ public class EntityEnderDragon extends EntityComplex {
         return adouble;
     }
 
-    public void d() {
+    public void e() {
         this.n = this.o;
         if (!this.world.isStatic) {
             this.datawatcher.watch(16, Integer.valueOf(this.health));
@@ -104,7 +104,7 @@ public class EntityEnderDragon extends EntityComplex {
             f1 = (this.random.nextFloat() - 0.5F) * 8.0F;
             this.world.a("largeexplode", this.locX + (double) f, this.locY + 2.0D + (double) d05, this.locZ + (double) f1, 0.0D, 0.0D, 0.0D);
         } else {
-            this.v();
+            this.A();
             f = 0.2F / (MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 10.0F + 1.0F);
             f *= (float) Math.pow(2.0D, this.motY);
             if (this.q) {
@@ -184,7 +184,7 @@ public class EntityEnderDragon extends EntityComplex {
                 }
 
                 if (this.p || d3 < 100.0D || d3 > 22500.0D || this.positionChanged || this.bz) {
-                    this.B();
+                    this.E();
                 }
 
                 d1 /= (double) MathHelper.sqrt(d0 * d0 + d2 * d2);
@@ -280,14 +280,14 @@ public class EntityEnderDragon extends EntityComplex {
             float f11 = MathHelper.sin(f10);
             float f12 = MathHelper.cos(f10);
 
-            this.h.y_();
+            this.h.G_();
             this.h.setPositionRotation(this.locX + (double) (f11 * 0.5F), this.locY, this.locZ - (double) (f12 * 0.5F), 0.0F, 0.0F);
-            this.l.y_();
+            this.l.G_();
             this.l.setPositionRotation(this.locX + (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ + (double) (f11 * 4.5F), 0.0F, 0.0F);
-            this.m.y_();
+            this.m.G_();
             this.m.setPositionRotation(this.locX - (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ - (double) (f11 * 4.5F), 0.0F, 0.0F);
             if (!this.world.isStatic) {
-                this.z();
+                this.D();
             }
 
             if (!this.world.isStatic && this.at == 0) {
@@ -302,7 +302,7 @@ public class EntityEnderDragon extends EntityComplex {
             f3 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F - this.aY * 0.01F);
             float f13 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F - this.aY * 0.01F);
 
-            this.g.y_();
+            this.g.G_();
             this.g.setPositionRotation(this.locX + (double) (f3 * 5.5F * f1), this.locY + (adouble1[1] - adouble[1]) * 1.0D + (double) (f9 * 5.5F), this.locZ - (double) (f13 * 5.5F * f1), 0.0F, 0.0F);
 
             for (int j = 0; j < 3; ++j) {
@@ -327,7 +327,7 @@ public class EntityEnderDragon extends EntityComplex {
                 float f17 = 1.5F;
                 float f18 = (float) (j + 1) * 2.0F;
 
-                entitycomplexpart.y_();
+                entitycomplexpart.G_();
                 entitycomplexpart.setPositionRotation(this.locX - (double) ((f11 * f17 + f15 * f18) * f1), this.locY + (adouble2[1] - adouble[1]) * 1.0D - (double) ((f18 + f17) * f9) + 1.5D, this.locZ + (double) ((f12 * f17 + f16 * f18) * f1), 0.0F, 0.0F);
             }
 
@@ -337,7 +337,7 @@ public class EntityEnderDragon extends EntityComplex {
         }
     }
 
-    private void v() {
+    private void A() {
         if (this.s != null) {
             if (this.s.dead) {
                 if (!this.world.isStatic) {
@@ -366,7 +366,7 @@ public class EntityEnderDragon extends EntityComplex {
 
             while (iterator.hasNext()) {
                 Entity entity = (Entity) iterator.next();
-                double d1 = entity.i(this);
+                double d1 = entity.j(this);
 
                 if (d1 < d0) {
                     d0 = d1;
@@ -378,14 +378,7 @@ public class EntityEnderDragon extends EntityComplex {
         }
     }
 
-    private void z() {
-        if (this.ticksLived % 20 == 0) {
-            Vec3D vec3d = this.e(1.0F);
-            double d0 = 0.0D;
-            double d1 = -1.0D;
-            double d2 = 0.0D;
-        }
-    }
+    private void D() {}
 
     private void a(List list) {
         double d0 = (this.h.boundingBox.a + this.h.boundingBox.d) / 2.0D;
@@ -427,7 +420,7 @@ public class EntityEnderDragon extends EntityComplex {
         }
     }
 
-    private void B() {
+    private void E() {
         this.p = false;
         if (this.random.nextInt(2) == 0 && this.world.players.size() > 0) {
             this.u = (Entity) this.world.players.get(this.random.nextInt(this.world.players.size()));
@@ -542,7 +535,7 @@ public class EntityEnderDragon extends EntityComplex {
         return true;
     }
 
-    protected void an() {
+    protected void aA() {
         ++this.r;
         if (this.r >= 180 && this.r <= 200) {
             float f = (this.random.nextFloat() - 0.5F) * 8.0F;
@@ -586,54 +579,54 @@ public class EntityEnderDragon extends EntityComplex {
             }
 
             this.a(MathHelper.floor(this.locX), MathHelper.floor(this.locZ));
-            this.ay();
+            this.aG();
             this.die();
         }
     }
 
     private void a(int i, int j) {
-        int k = this.world.height / 2;
+        byte b0 = 64;
 
         BlockEnderPortal.a = true;
-        byte b0 = 4;
+        byte b1 = 4;
 
         // CraftBukkit start - Replace any "this.world" in the following with just "world"!
         EntityCreatePortalEvent event = new EntityCreatePortalEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), new ArrayList<BlockState>(), PortalType.ENDER);
         BlockStateListPopulator world = new BlockStateListPopulator(this.world.getWorld(), event.getBlocks());
 
-        for (int l = k - 1; l <= k + 32; ++l) {
-            for (int i1 = i - b0; i1 <= i + b0; ++i1) {
-                for (int j1 = j - b0; j1 <= j + b0; ++j1) {
-                    double d0 = (double) (i1 - i);
-                    double d1 = (double) (j1 - j);
+        for (int k = b0 - 1; k <= b0 + 32; ++k) {
+            for (int l = i - b1; l <= i + b1; ++l) {
+                for (int i1 = j - b1; i1 <= j + b1; ++i1) {
+                    double d0 = (double) (l - i);
+                    double d1 = (double) (i1 - j);
                     double d2 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1);
 
-                    if (d2 <= (double) b0 - 0.5D) {
-                        if (l < k) {
-                            if (d2 <= (double) (b0 - 1) - 0.5D) {
-                                world.setTypeId(i1, l, j1, Block.BEDROCK.id);
+                    if (d2 <= (double) b1 - 0.5D) {
+                        if (k < b0) {
+                            if (d2 <= (double) (b1 - 1) - 0.5D) {
+                                this.world.setTypeId(l, k, i1, Block.BEDROCK.id);
                             }
-                        } else if (l > k) {
-                            world.setTypeId(i1, l, j1, 0);
-                        } else if (d2 > (double) (b0 - 1) - 0.5D) {
-                            world.setTypeId(i1, l, j1, Block.BEDROCK.id);
+                        } else if (k > b0) {
+                            this.world.setTypeId(l, k, i1, 0);
+                        } else if (d2 > (double) (b1 - 1) - 0.5D) {
+                            this.world.setTypeId(l, k, i1, Block.BEDROCK.id);
                         } else {
-                            world.setTypeId(i1, l, j1, Block.ENDER_PORTAL.id);
+                            this.world.setTypeId(l, k, i1, Block.ENDER_PORTAL.id);
                         }
                     }
                 }
             }
         }
 
-        world.setTypeId(i, k + 0, j, Block.BEDROCK.id);
-        world.setTypeId(i, k + 1, j, Block.BEDROCK.id);
-        world.setTypeId(i, k + 2, j, Block.BEDROCK.id);
-        world.setTypeId(i - 1, k + 2, j, Block.TORCH.id);
-        world.setTypeId(i + 1, k + 2, j, Block.TORCH.id);
-        world.setTypeId(i, k + 2, j - 1, Block.TORCH.id);
-        world.setTypeId(i, k + 2, j + 1, Block.TORCH.id);
-        world.setTypeId(i, k + 3, j, Block.BEDROCK.id);
-        world.setTypeId(i, k + 4, j, Block.DRAGON_EGG.id);
+        this.world.setTypeId(i, b0 + 0, j, Block.BEDROCK.id);
+        this.world.setTypeId(i, b0 + 1, j, Block.BEDROCK.id);
+        this.world.setTypeId(i, b0 + 2, j, Block.BEDROCK.id);
+        this.world.setTypeId(i - 1, b0 + 2, j, Block.TORCH.id);
+        this.world.setTypeId(i + 1, b0 + 2, j, Block.TORCH.id);
+        this.world.setTypeId(i, b0 + 2, j - 1, Block.TORCH.id);
+        this.world.setTypeId(i, b0 + 2, j + 1, Block.TORCH.id);
+        this.world.setTypeId(i, b0 + 3, j, Block.BEDROCK.id);
+        this.world.setTypeId(i, b0 + 4, j, Block.DRAGON_EGG.id);
 
         this.world.getServer().getPluginManager().callEvent(event);
 
@@ -647,13 +640,13 @@ public class EntityEnderDragon extends EntityComplex {
         BlockEnderPortal.a = false;
     }
 
-    protected void au() {}
+    protected void aF() {}
 
-    public Entity[] aR() {
+    public Entity[] ba() {
         return this.children;
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return false;
     }
 
diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java
index 1c45dcef26..ecd82cb3e9 100644
--- a/src/main/java/net/minecraft/server/EntityEnderman.java
+++ b/src/main/java/net/minecraft/server/EntityEnderman.java
@@ -63,8 +63,8 @@ public class EntityEnderman extends EntityMonster {
         return null;
     }
 
-    public float a(float f) {
-        return super.a(f);
+    public float b(float f) {
+        return super.b(f);
     }
 
     private boolean c(EntityHuman entityhuman) {
@@ -73,19 +73,19 @@ public class EntityEnderman extends EntityMonster {
         if (itemstack != null && itemstack.id == Block.PUMPKIN.id) {
             return false;
         } else {
-            Vec3D vec3d = entityhuman.e(1.0F).b();
+            Vec3D vec3d = entityhuman.f(1.0F).b();
             Vec3D vec3d1 = Vec3D.create(this.locX - entityhuman.locX, this.boundingBox.b + (double) (this.length / 2.0F) - (entityhuman.locY + (double) entityhuman.getHeadHeight()), this.locZ - entityhuman.locZ);
             double d0 = vec3d1.c();
 
             vec3d1 = vec3d1.b();
             double d1 = vec3d.a(vec3d1);
 
-            return d1 > 1.0D - 0.025D / d0 ? entityhuman.g(this) : false;
+            return d1 > 1.0D - 0.025D / d0 ? entityhuman.h(this) : false;
         }
     }
 
-    public void d() {
-        if (this.aJ()) {
+    public void e() {
+        if (this.aS()) {
             this.damageEntity(DamageSource.DROWN, 1);
         }
 
@@ -139,17 +139,17 @@ public class EntityEnderman extends EntityMonster {
         }
 
         if (this.world.e() && !this.world.isStatic) {
-            float f = this.a(1.0F);
+            float f = this.b(1.0F);
 
             if (f > 0.5F && this.world.isChunkLoaded(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
                 this.target = null;
-                this.w_();
+                this.x();
             }
         }
 
-        if (this.aJ()) {
+        if (this.aS()) {
             this.target = null;
-            this.w_();
+            this.x();
         }
 
         this.aZ = false;
@@ -162,12 +162,12 @@ public class EntityEnderman extends EntityMonster {
                 if (this.target instanceof EntityHuman && this.c((EntityHuman) this.target)) {
                     this.aW = this.aX = 0.0F;
                     this.bb = 0.0F;
-                    if (this.target.i(this) < 16.0D) {
-                        this.w_();
+                    if (this.target.j(this) < 16.0D) {
+                        this.x();
                     }
 
                     this.g = 0;
-                } else if (this.target.i(this) > 256.0D && this.g++ >= 30 && this.f(this.target)) {
+                } else if (this.target.j(this) > 256.0D && this.g++ >= 30 && this.e(this.target)) {
                     this.g = 0;
                 }
             } else {
@@ -175,10 +175,10 @@ public class EntityEnderman extends EntityMonster {
             }
         }
 
-        super.d();
+        super.e();
     }
 
-    protected boolean w_() {
+    protected boolean x() {
         double d0 = this.locX + (this.random.nextDouble() - 0.5D) * 64.0D;
         double d1 = this.locY + (double) (this.random.nextInt(64) - 32);
         double d2 = this.locZ + (this.random.nextDouble() - 0.5D) * 64.0D;
@@ -186,7 +186,7 @@ public class EntityEnderman extends EntityMonster {
         return this.b(d0, d1, d2);
     }
 
-    protected boolean f(Entity entity) {
+    protected boolean e(Entity entity) {
         Vec3D vec3d = Vec3D.create(this.locX - entity.locX, this.boundingBox.b + (double) (this.length / 2.0F) - entity.locY + (double) entity.getHeadHeight(), this.locZ - entity.locZ);
 
         vec3d = vec3d.b();
@@ -267,15 +267,15 @@ public class EntityEnderman extends EntityMonster {
         }
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.endermen.idle";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.endermen.hit";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.endermen.death";
     }
 
@@ -319,7 +319,7 @@ public class EntityEnderman extends EntityMonster {
     public boolean damageEntity(DamageSource damagesource, int i) {
         if (damagesource instanceof EntityDamageSourceIndirect) {
             for (int j = 0; j < 64; ++j) {
-                if (this.w_()) {
+                if (this.x()) {
                     return true;
                 }
             }
diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
index 8945bf3225..15cd2b224a 100644
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java
+++ b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
@@ -34,8 +34,8 @@ public class EntityExperienceOrb extends Entity {
 
     protected void b() {}
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         if (this.c > 0) {
             --this.c;
         }
@@ -102,7 +102,7 @@ public class EntityExperienceOrb extends Entity {
         }
     }
 
-    public boolean i_() {
+    public boolean h_() {
         return this.world.a(this.boundingBox, Material.WATER, this);
     }
 
@@ -111,7 +111,7 @@ public class EntityExperienceOrb extends Entity {
     }
 
     public boolean damageEntity(DamageSource damagesource, int i) {
-        this.aM();
+        this.aV();
         this.d -= i;
         if (this.d <= 0) {
             this.die();
@@ -144,7 +144,7 @@ public class EntityExperienceOrb extends Entity {
         }
     }
 
-    public int g() {
+    public int y_() {
         return this.value;
     }
 
@@ -170,4 +170,8 @@ public class EntityExperienceOrb extends Entity {
 
         return i >= 2477 ? 2477 : (i >= 1237 ? 1237 : (i >= 617 ? 617 : (i >= 307 ? 307 : (i >= 149 ? 149 : (i >= 73 ? 73 : (i >= 37 ? 37 : (i >= 17 ? 17 : (i >= 7 ? 7 : (i >= 3 ? 3 : 1)))))))));
     }
+
+    public boolean k_() {
+        return false;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java
index 317308675d..72ab660f0b 100644
--- a/src/main/java/net/minecraft/server/EntityFallingBlock.java
+++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java
@@ -33,11 +33,11 @@ public class EntityFallingBlock extends Entity {
 
     protected void b() {}
 
-    public boolean e_() {
+    public boolean o_() {
         return !this.dead;
     }
 
-    public void y_() {
+    public void G_() {
         if (this.id == 0) {
             this.die();
         } else {
@@ -71,7 +71,7 @@ public class EntityFallingBlock extends Entity {
                         this.b(this.id, 1);
                     }
                 }
-            } else if (this.b > 100 && !this.world.isStatic) {
+            } else if (this.b > 100 && !this.world.isStatic && (j < 1 || j > 256) || this.b > 600) {
                 this.b(this.id, 1);
                 this.die();
             }
diff --git a/src/main/java/net/minecraft/server/EntityFireball.java b/src/main/java/net/minecraft/server/EntityFireball.java
index 341a248a23..ae7cd6f846 100644
--- a/src/main/java/net/minecraft/server/EntityFireball.java
+++ b/src/main/java/net/minecraft/server/EntityFireball.java
@@ -34,6 +34,18 @@ public class EntityFireball extends Entity {
 
     protected void b() {}
 
+    public EntityFireball(World world, double d0, double d1, double d2, double d3, double d4, double d5) {
+        super(world);
+        this.b(1.0F, 1.0F);
+        this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch);
+        this.setPosition(d0, d1, d2);
+        double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
+
+        this.dirX = d3 / d6 * 0.1D;
+        this.dirY = d4 / d6 * 0.1D;
+        this.dirZ = d5 / d6 * 0.1D;
+    }
+
     public EntityFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) {
         super(world);
         this.shooter = entityliving;
@@ -58,121 +70,121 @@ public class EntityFireball extends Entity {
         this.dirZ = d2 / d3 * 0.1D;
     }
 
-    public void y_() {
-        super.y_();
-        this.setOnFire(1);
-        if (!this.world.isStatic && (this.shooter == null || this.shooter.dead)) {
+    public void G_() {
+        if (!this.world.isStatic && (this.shooter != null && this.shooter.dead || !this.world.isLoaded((int) this.locX, (int) this.locY, (int) this.locZ))) {
             this.die();
-        }
+        } else {
+            super.G_();
+            this.setOnFire(1);
+            if (this.i) {
+                int i = this.world.getTypeId(this.e, this.f, this.g);
 
-        if (this.i) {
-            int i = this.world.getTypeId(this.e, this.f, this.g);
+                if (i == this.h) {
+                    ++this.j;
+                    if (this.j == 600) {
+                        this.die();
+                    }
 
-            if (i == this.h) {
-                ++this.j;
-                if (this.j == 1200) {
-                    this.die();
+                    return;
                 }
 
-                return;
+                this.i = false;
+                this.motX *= (double) (this.random.nextFloat() * 0.2F);
+                this.motY *= (double) (this.random.nextFloat() * 0.2F);
+                this.motZ *= (double) (this.random.nextFloat() * 0.2F);
+                this.j = 0;
+                this.k = 0;
+            } else {
+                ++this.k;
             }
 
-            this.i = false;
-            this.motX *= (double) (this.random.nextFloat() * 0.2F);
-            this.motY *= (double) (this.random.nextFloat() * 0.2F);
-            this.motZ *= (double) (this.random.nextFloat() * 0.2F);
-            this.j = 0;
-            this.k = 0;
-        } else {
-            ++this.k;
-        }
+            Vec3D vec3d = Vec3D.create(this.locX, this.locY, this.locZ);
+            Vec3D vec3d1 = Vec3D.create(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ);
+            MovingObjectPosition movingobjectposition = this.world.a(vec3d, vec3d1);
 
-        Vec3D vec3d = Vec3D.create(this.locX, this.locY, this.locZ);
-        Vec3D vec3d1 = Vec3D.create(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ);
-        MovingObjectPosition movingobjectposition = this.world.a(vec3d, vec3d1);
+            vec3d = Vec3D.create(this.locX, this.locY, this.locZ);
+            vec3d1 = Vec3D.create(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ);
+            if (movingobjectposition != null) {
+                vec3d1 = Vec3D.create(movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c);
+            }
 
-        vec3d = Vec3D.create(this.locX, this.locY, this.locZ);
-        vec3d1 = Vec3D.create(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ);
-        if (movingobjectposition != null) {
-            vec3d1 = Vec3D.create(movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c);
-        }
+            Entity entity = null;
+            List list = this.world.getEntities(this, this.boundingBox.a(this.motX, this.motY, this.motZ).grow(1.0D, 1.0D, 1.0D));
+            double d0 = 0.0D;
 
-        Entity entity = null;
-        List list = this.world.getEntities(this, this.boundingBox.a(this.motX, this.motY, this.motZ).grow(1.0D, 1.0D, 1.0D));
-        double d0 = 0.0D;
+            for (int j = 0; j < list.size(); ++j) {
+                Entity entity1 = (Entity) list.get(j);
 
-        for (int j = 0; j < list.size(); ++j) {
-            Entity entity1 = (Entity) list.get(j);
+                if (entity1.o_() && (!entity1.a_((Entity) this.shooter) || this.k >= 25)) {
+                    float f = 0.3F;
+                    AxisAlignedBB axisalignedbb = entity1.boundingBox.grow((double) f, (double) f, (double) f);
+                    MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
 
-            if (entity1.e_() && (!entity1.a((Entity) this.shooter) || this.k >= 25)) {
-                float f = 0.3F;
-                AxisAlignedBB axisalignedbb = entity1.boundingBox.grow((double) f, (double) f, (double) f);
-                MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
+                    if (movingobjectposition1 != null) {
+                        double d1 = vec3d.distanceSquared(movingobjectposition1.pos); // CraftBukkit - distance efficiency
 
-                if (movingobjectposition1 != null) {
-                    double d1 = vec3d.distanceSquared(movingobjectposition1.pos); // CraftBukkit - distance efficiency
-
-                    if (d1 < d0 || d0 == 0.0D) {
-                        entity = entity1;
-                        d0 = d1;
+                        if (d1 < d0 || d0 == 0.0D) {
+                            entity = entity1;
+                            d0 = d1;
+                        }
                     }
                 }
             }
-        }
 
-        if (entity != null) {
-            movingobjectposition = new MovingObjectPosition(entity);
-        }
-
-        if (movingobjectposition != null) {
-            this.a(movingobjectposition);
-        }
-
-        this.locX += this.motX;
-        this.locY += this.motY;
-        this.locZ += this.motZ;
-        float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ);
-
-        this.yaw = (float) (Math.atan2(this.motX, this.motZ) * 180.0D / 3.1415927410125732D);
-
-        for (this.pitch = (float) (Math.atan2(this.motY, (double) f1) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) {
-            ;
-        }
-
-        while (this.pitch - this.lastPitch >= 180.0F) {
-            this.lastPitch += 360.0F;
-        }
-
-        while (this.yaw - this.lastYaw < -180.0F) {
-            this.lastYaw -= 360.0F;
-        }
-
-        while (this.yaw - this.lastYaw >= 180.0F) {
-            this.lastYaw += 360.0F;
-        }
-
-        this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F;
-        this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F;
-        float f2 = 0.95F;
-
-        if (this.aK()) {
-            for (int k = 0; k < 4; ++k) {
-                float f3 = 0.25F;
-
-                this.world.a("bubble", this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ);
+            if (entity != null) {
+                movingobjectposition = new MovingObjectPosition(entity);
             }
 
-            f2 = 0.8F;
-        }
+            if (movingobjectposition != null) {
+                this.a(movingobjectposition);
+            }
 
-        this.motX += this.dirX;
-        this.motY += this.dirY;
-        this.motZ += this.dirZ;
-        this.motX *= (double) f2;
-        this.motY *= (double) f2;
-        this.motZ *= (double) f2;
-        this.world.a("smoke", this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D);
-        this.setPosition(this.locX, this.locY, this.locZ);
+            this.locX += this.motX;
+            this.locY += this.motY;
+            this.locZ += this.motZ;
+            float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ);
+
+            this.yaw = (float) (Math.atan2(this.motX, this.motZ) * 180.0D / 3.1415927410125732D);
+
+            for (this.pitch = (float) (Math.atan2(this.motY, (double) f1) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) {
+                ;
+            }
+
+            while (this.pitch - this.lastPitch >= 180.0F) {
+                this.lastPitch += 360.0F;
+            }
+
+            while (this.yaw - this.lastYaw < -180.0F) {
+                this.lastYaw -= 360.0F;
+            }
+
+            while (this.yaw - this.lastYaw >= 180.0F) {
+                this.lastYaw += 360.0F;
+            }
+
+            this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F;
+            this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F;
+            float f2 = 0.95F;
+
+            if (this.aT()) {
+                for (int k = 0; k < 4; ++k) {
+                    float f3 = 0.25F;
+
+                    this.world.a("bubble", this.locX - this.motX * (double) f3, this.locY - this.motY * (double) f3, this.locZ - this.motZ * (double) f3, this.motX, this.motY, this.motZ);
+                }
+
+                f2 = 0.8F;
+            }
+
+            this.motX += this.dirX;
+            this.motY += this.dirY;
+            this.motZ += this.dirZ;
+            this.motX *= (double) f2;
+            this.motY *= (double) f2;
+            this.motZ *= (double) f2;
+            this.world.a("smoke", this.locX, this.locY + 0.5D, this.locZ, 0.0D, 0.0D, 0.0D);
+            this.setPosition(this.locX, this.locY, this.locZ);
+        }
     }
 
     protected void a(MovingObjectPosition movingobjectposition) {
@@ -221,7 +233,7 @@ public class EntityFireball extends Entity {
         this.i = nbttagcompound.getByte("inGround") == 1;
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return true;
     }
 
@@ -230,9 +242,9 @@ public class EntityFireball extends Entity {
     }
 
     public boolean damageEntity(DamageSource damagesource, int i) {
-        this.aM();
+        this.aV();
         if (damagesource.getEntity() != null) {
-            Vec3D vec3d = damagesource.getEntity().aA();
+            Vec3D vec3d = damagesource.getEntity().aI();
 
             if (vec3d != null) {
                 this.motX = vec3d.a;
@@ -253,7 +265,7 @@ public class EntityFireball extends Entity {
         }
     }
 
-    public float a(float f) {
+    public float b(float f) {
         return 1.0F;
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityFishingHook.java b/src/main/java/net/minecraft/server/EntityFishingHook.java
index 40818045ee..1c54ec2a0b 100644
--- a/src/main/java/net/minecraft/server/EntityFishingHook.java
+++ b/src/main/java/net/minecraft/server/EntityFishingHook.java
@@ -74,8 +74,8 @@ public class EntityFishingHook extends Entity {
         this.i = 0;
     }
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         if (this.l > 0) {
             double d0 = this.locX + (this.m - this.locX) / (double) this.l;
             double d1 = this.locY + (this.n - this.locY) / (double) this.l;
@@ -98,9 +98,9 @@ public class EntityFishingHook extends Entity {
             this.c(this.yaw, this.pitch);
         } else {
             if (!this.world.isStatic) {
-                ItemStack itemstack = this.owner.Q();
+                ItemStack itemstack = this.owner.T();
 
-                if (this.owner.dead || !this.owner.isAlive() || itemstack == null || itemstack.getItem() != Item.FISHING_ROD || this.i(this.owner) > 1024.0D) {
+                if (this.owner.dead || !this.owner.isAlive() || itemstack == null || itemstack.getItem() != Item.FISHING_ROD || this.j(this.owner) > 1024.0D) {
                     this.die();
                     this.owner.hookedFish = null;
                     return;
@@ -163,7 +163,7 @@ public class EntityFishingHook extends Entity {
             for (int j = 0; j < list.size(); ++j) {
                 Entity entity1 = (Entity) list.get(j);
 
-                if (entity1.e_() && (entity1 != this.owner || this.j >= 5)) {
+                if (entity1.o_() && (entity1 != this.owner || this.j >= 5)) {
                     float f = 0.3F;
                     AxisAlignedBB axisalignedbb = entity1.boundingBox.grow((double) f, (double) f, (double) f);
                     MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
@@ -242,7 +242,7 @@ public class EntityFishingHook extends Entity {
                     } else {
                         short short1 = 500;
 
-                        if (this.world.v(MathHelper.floor(this.locX), MathHelper.floor(this.locY) + 1, MathHelper.floor(this.locZ))) {
+                        if (this.world.y(MathHelper.floor(this.locX), MathHelper.floor(this.locY) + 1, MathHelper.floor(this.locZ))) {
                             short1 = 300;
                         }
 
@@ -308,7 +308,7 @@ public class EntityFishingHook extends Entity {
         this.h = nbttagcompound.getByte("inGround") == 1;
     }
 
-    public int j() {
+    public int k() {
         byte b0 = 0;
 
         if (this.hooked != null) {
diff --git a/src/main/java/net/minecraft/server/EntityGhast.java b/src/main/java/net/minecraft/server/EntityGhast.java
index e1b5709092..ac3282b838 100644
--- a/src/main/java/net/minecraft/server/EntityGhast.java
+++ b/src/main/java/net/minecraft/server/EntityGhast.java
@@ -46,19 +46,19 @@ public class EntityGhast extends EntityFlying implements IMonster {
         return 10;
     }
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         byte b0 = this.datawatcher.getByte(16);
 
         this.texture = b0 == 1 ? "/mob/ghast_fire.png" : "/mob/ghast.png";
     }
 
-    protected void m_() {
+    protected void d_() {
         if (!this.world.isStatic && this.world.difficulty == 0) {
             this.die();
         }
 
-        this.au();
+        this.aF();
         this.e = this.f;
         double d0 = this.b - this.locX;
         double d1 = this.c - this.locY;
@@ -122,13 +122,13 @@ public class EntityGhast extends EntityFlying implements IMonster {
 
         double d4 = 64.0D;
 
-        if (this.target != null && this.target.i(this) < d4 * d4) {
+        if (this.target != null && this.target.j(this) < d4 * d4) {
             double d5 = this.target.locX - this.locX;
             double d6 = this.target.boundingBox.b + (double) (this.target.length / 2.0F) - (this.locY + (double) (this.length / 2.0F));
             double d7 = this.target.locZ - this.locZ;
 
             this.V = this.yaw = -((float) Math.atan2(d5, d7)) * 180.0F / 3.1415927F;
-            if (this.g(this.target)) {
+            if (this.h(this.target)) {
                 if (this.f == 10) {
                     this.world.a((EntityHuman) null, 1007, (int) this.locX, (int) this.locY, (int) this.locZ, 0);
                 }
@@ -138,7 +138,7 @@ public class EntityGhast extends EntityFlying implements IMonster {
                     this.world.a((EntityHuman) null, 1008, (int) this.locX, (int) this.locY, (int) this.locZ, 0);
                     EntityFireball entityfireball = new EntityFireball(this.world, this, d5, d6, d7);
                     double d8 = 4.0D;
-                    Vec3D vec3d = this.e(1.0F);
+                    Vec3D vec3d = this.f(1.0F);
 
                     entityfireball.locX = this.locX + vec3d.a * d8;
                     entityfireball.locY = this.locY + (double) (this.length / 2.0F) + 0.5D;
@@ -182,15 +182,15 @@ public class EntityGhast extends EntityFlying implements IMonster {
         return true;
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.ghast.moan";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.ghast.scream";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.ghast.death";
     }
 
@@ -219,7 +219,7 @@ public class EntityGhast extends EntityFlying implements IMonster {
         // CraftBukkit end
     }
 
-    protected float o() {
+    protected float p() {
         return 10.0F;
     }
 
@@ -227,7 +227,7 @@ public class EntityGhast extends EntityFlying implements IMonster {
         return this.random.nextInt(20) == 0 && super.canSpawn() && this.world.difficulty > 0;
     }
 
-    public int p() {
+    public int q() {
         return 1;
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java
index 3441f1e04a..24fc1292c3 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -96,43 +96,43 @@ public abstract class EntityHuman extends EntityLiving {
         this.datawatcher.a(17, Byte.valueOf((byte) 0));
     }
 
-    public boolean I() {
+    public boolean L() {
         return this.d != null;
     }
 
-    public void J() {
+    public void M() {
         if (this.d != null) {
-            this.d.a(this.world, this, this.e);
+            this.d.b(this.world, this, this.e);
         }
 
-        this.K();
+        this.N();
     }
 
-    public void K() {
+    public void N() {
         this.d = null;
         this.e = 0;
         if (!this.world.isStatic) {
-            this.h(false);
+            this.i(false);
         }
     }
 
-    public boolean L() {
-        return this.I() && Item.byId[this.d.id].d(this.d) == EnumAnimation.d;
+    public boolean O() {
+        return this.L() && Item.byId[this.d.id].d(this.d) == EnumAnimation.d;
     }
 
-    public void y_() {
+    public void G_() {
         if (this.d != null) {
             ItemStack itemstack = this.inventory.getItemInHand();
 
             if (itemstack != this.d) {
-                this.K();
+                this.N();
             } else {
                 if (this.e <= 25 && this.e % 4 == 0) {
                     this.b(itemstack, 5);
                 }
 
                 if (--this.e == 0 && !this.world.isStatic) {
-                    this.H();
+                    this.K();
                 }
             }
         }
@@ -148,7 +148,7 @@ public abstract class EntityHuman extends EntityLiving {
             }
 
             if (!this.world.isStatic) {
-                if (!this.B()) {
+                if (!this.G()) {
                     this.a(true, true, false);
                 } else if (this.world.e()) {
                     this.a(false, true, true);
@@ -161,7 +161,7 @@ public abstract class EntityHuman extends EntityLiving {
             }
         }
 
-        super.y_();
+        super.G_();
         if (!this.world.isStatic && this.activeContainer != null && !this.activeContainer.b(this)) {
             this.closeInventory();
             this.activeContainer = this.defaultContainer;
@@ -245,7 +245,7 @@ public abstract class EntityHuman extends EntityLiving {
         }
     }
 
-    protected void H() {
+    protected void K() {
         if (this.d != null) {
             this.b(this.d, 16);
             int i = this.d.count;
@@ -258,11 +258,11 @@ public abstract class EntityHuman extends EntityLiving {
                 }
             }
 
-            this.K();
+            this.N();
         }
     }
 
-    protected boolean M() {
+    protected boolean P() {
         return this.getHealth() <= 0 || this.isSleeping();
     }
 
@@ -271,23 +271,23 @@ public abstract class EntityHuman extends EntityLiving {
         this.activeContainer = this.defaultContainer;
     }
 
-    public void N() {
+    public void Q() {
         double d0 = this.locX;
         double d1 = this.locY;
         double d2 = this.locZ;
 
-        super.N();
+        super.Q();
         this.r = this.s;
         this.s = 0.0F;
         this.h(this.locX - d0, this.locY - d1, this.locZ - d2);
     }
 
-    private int v() {
+    private int E() {
         return this.hasEffect(MobEffectList.FASTER_DIG) ? 6 - (1 + this.getEffect(MobEffectList.FASTER_DIG).getAmplifier()) * 1 : (this.hasEffect(MobEffectList.SLOWER_DIG) ? 6 + (1 + this.getEffect(MobEffectList.SLOWER_DIG).getAmplifier()) * 2 : 6);
     }
 
-    protected void m_() {
-        int i = this.v();
+    protected void d_() {
+        int i = this.E();
 
         if (this.t) {
             ++this.u;
@@ -302,7 +302,7 @@ public abstract class EntityHuman extends EntityLiving {
         this.ao = (float) this.u / (float) i;
     }
 
-    public void d() {
+    public void e() {
         if (this.o > 0) {
             --this.o;
         }
@@ -314,7 +314,7 @@ public abstract class EntityHuman extends EntityLiving {
 
         this.inventory.i();
         this.r = this.s;
-        super.d();
+        super.e();
         this.al = this.P;
         this.am = this.Q;
         if (this.isSprinting()) {
@@ -348,14 +348,14 @@ public abstract class EntityHuman extends EntityLiving {
                     Entity entity = (Entity) list.get(i);
 
                     if (!entity.dead) {
-                        this.k(entity);
+                        this.l(entity);
                     }
                 }
             }
         }
     }
 
-    private void k(Entity entity) {
+    private void l(Entity entity) {
         entity.a_(this);
     }
 
@@ -389,22 +389,24 @@ public abstract class EntityHuman extends EntityLiving {
         }
     }
 
-    protected int f(int i) {
+    protected int b_(int i) {
         int j = EnchantmentManager.getOxygenEnchantmentLevel(this.inventory);
 
-        return j > 0 && this.random.nextInt(j + 1) > 0 ? i : super.f(i);
+        return j > 0 && this.random.nextInt(j + 1) > 0 ? i : super.b_(i);
     }
 
-    public void O() {
-        this.a(this.inventory.splitStack(this.inventory.itemInHandIndex, 1), false);
+    public EntityItem R() {
+        return this.a(this.inventory.splitStack(this.inventory.itemInHandIndex, 1), false);
     }
 
-    public void drop(ItemStack itemstack) {
-        this.a(itemstack, false);
+    public EntityItem drop(ItemStack itemstack) {
+        return this.a(itemstack, false);
     }
 
-    public void a(ItemStack itemstack, boolean flag) {
-        if (itemstack != null) {
+    public EntityItem a(ItemStack itemstack, boolean flag) {
+        if (itemstack == null) {
+            return null;
+        } else {
             EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY - 0.30000001192092896D + (double) this.getHeadHeight(), this.locZ, itemstack);
 
             entityitem.pickupDelay = 40;
@@ -440,12 +442,13 @@ public abstract class EntityHuman extends EntityLiving {
 
             if (event.isCancelled()) {
                 player.getInventory().addItem(drop.getItemStack());
-                return;
+                return null;
             }
             // CraftBukkit end
 
             this.a(entityitem);
             this.a(StatisticList.v, 1);
+            return entityitem;
         }
     }
 
@@ -548,7 +551,7 @@ public abstract class EntityHuman extends EntityLiving {
         return 0.12F;
     }
 
-    protected void r_() {
+    protected void A() {
         this.height = 1.62F;
     }
 
@@ -645,7 +648,7 @@ public abstract class EntityHuman extends EntityLiving {
         }
     }
 
-    protected boolean z() {
+    protected boolean C_() {
         return false;
     }
 
@@ -659,7 +662,7 @@ public abstract class EntityHuman extends EntityLiving {
                 }
             }
 
-            if (!(entityliving instanceof EntityHuman) || this.z()) {
+            if (!(entityliving instanceof EntityHuman) || this.C_()) {
                 List list = this.world.a(EntityWolf.class, AxisAlignedBB.b(this.locX, this.locY, this.locZ, this.locX + 1.0D, this.locY + 1.0D, this.locZ + 1.0D).grow(16.0D, 4.0D, 16.0D));
                 Iterator iterator = list.iterator();
 
@@ -667,7 +670,7 @@ public abstract class EntityHuman extends EntityLiving {
                     Entity entity = (Entity) iterator.next();
                     EntityWolf entitywolf1 = (EntityWolf) entity;
 
-                    if (entitywolf1.isTamed() && entitywolf1.F() == null && this.name.equals(entitywolf1.getOwnerName()) && (!flag || !entitywolf1.isSitting())) {
+                    if (entitywolf1.isTamed() && entitywolf1.H() == null && this.name.equals(entitywolf1.getOwnerName()) && (!flag || !entitywolf1.isSitting())) {
                         // CraftBukkit start
                         org.bukkit.entity.Entity bukkitTarget = entity == null ? null : entityliving.getBukkitEntity();
 
@@ -692,16 +695,16 @@ public abstract class EntityHuman extends EntityLiving {
         }
     }
 
-    protected void g(int i) {
-        this.inventory.d(i);
+    protected void f(int i) {
+        this.inventory.e(i);
     }
 
-    public int P() {
+    public int S() {
         return this.inventory.j();
     }
 
     protected void c(DamageSource damagesource, int i) {
-        if (!damagesource.ignoresArmor() && this.L()) {
+        if (!damagesource.ignoresArmor() && this.O()) {
             i = 1 + i >> 1;
         }
 
@@ -721,146 +724,150 @@ public abstract class EntityHuman extends EntityLiving {
 
     public void e(Entity entity) {
         if (!entity.b(this)) {
-            ItemStack itemstack = this.Q();
+            ItemStack itemstack = this.T();
 
             if (itemstack != null && entity instanceof EntityLiving) {
                 itemstack.a((EntityLiving) entity);
                 // CraftBukkit - bypass infinite items; <= 0 -> == 0
                 if (itemstack.count == 0) {
                     itemstack.a(this);
-                    this.R();
+                    this.U();
                 }
             }
         }
     }
 
-    public ItemStack Q() {
+    public ItemStack T() {
         return this.inventory.getItemInHand();
     }
 
-    public void R() {
+    public void U() {
         this.inventory.setItem(this.inventory.itemInHandIndex, (ItemStack) null);
     }
 
-    public double S() {
+    public double V() {
         return (double) (this.height - 0.5F);
     }
 
-    public void s_() {
-        if (!this.t || this.u >= this.v() / 2 || this.u < 0) {
+    public void D() {
+        if (!this.t || this.u >= this.E() / 2 || this.u < 0) {
             this.u = -1;
             this.t = true;
         }
     }
 
     public void attack(Entity entity) {
-        int i = this.inventory.a(entity);
+        if (entity.k_()) {
+            int i = this.inventory.a(entity);
 
-        if (this.hasEffect(MobEffectList.INCREASE_DAMAGE)) {
-            i += 3 << this.getEffect(MobEffectList.INCREASE_DAMAGE).getAmplifier();
-        }
-
-        if (this.hasEffect(MobEffectList.WEAKNESS)) {
-            i -= 2 << this.getEffect(MobEffectList.WEAKNESS).getAmplifier();
-        }
-
-        int j = 0;
-        int k = 0;
-
-        if (entity instanceof EntityLiving) {
-            k = EnchantmentManager.a(this.inventory, (EntityLiving) entity);
-            j += EnchantmentManager.getKnockbackEnchantmentLevel(this.inventory, (EntityLiving) entity);
-        }
-
-        if (this.isSprinting()) {
-            ++j;
-        }
-
-        if (i > 0 || k > 0) {
-            boolean flag = this.fallDistance > 0.0F && !this.onGround && !this.r() && !this.aK() && !this.hasEffect(MobEffectList.BLINDNESS) && this.vehicle == null && entity instanceof EntityLiving;
-
-            if (flag) {
-                i += this.random.nextInt(i / 2 + 2);
+            if (this.hasEffect(MobEffectList.INCREASE_DAMAGE)) {
+                i += 3 << this.getEffect(MobEffectList.INCREASE_DAMAGE).getAmplifier();
             }
 
-            // CraftBukkit start - Don't call the event when the entity is human since it will be called with damageEntity
-            if ((entity instanceof EntityLiving || entity instanceof EntityComplexPart || entity instanceof EntityEnderCrystal) && !(entity instanceof EntityHuman)) {
-                org.bukkit.entity.Entity damager = this.getBukkitEntity();
-                org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity();
-
-                EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, i);
-                Bukkit.getPluginManager().callEvent(event);
-
-                if (event.isCancelled() || event.getDamage() == 0) {
-                    return;
-                }
-
-                i = event.getDamage();
-            }
-            // CraftBukkit end
-
-            i += k;
-            boolean flag1 = entity.damageEntity(DamageSource.playerAttack(this), i);
-
-            // CraftBukkit start - Return when the damage fails so that the item will not lose durability
-            if (!flag1) {
-                return;
-            }
-            // CraftBukkit end
-
-            if (flag1) {
-                if (j > 0) {
-                    entity.b_((double) (-MathHelper.sin(this.yaw * 3.1415927F / 180.0F) * (float) j * 0.5F), 0.1D, (double) (MathHelper.cos(this.yaw * 3.1415927F / 180.0F) * (float) j * 0.5F));
-                    this.motX *= 0.6D;
-                    this.motZ *= 0.6D;
-                    this.setSprinting(false);
-                }
-
-                if (flag) {
-                    this.c(entity);
-                }
-
-                if (k > 0) {
-                    this.d(entity);
-                }
-
-                if (i >= 18) {
-                    this.a((Statistic) AchievementList.E);
-                }
+            if (this.hasEffect(MobEffectList.WEAKNESS)) {
+                i -= 2 << this.getEffect(MobEffectList.WEAKNESS).getAmplifier();
             }
 
-            ItemStack itemstack = this.Q();
-
-            if (itemstack != null && entity instanceof EntityLiving) {
-                itemstack.a((EntityLiving) entity, this);
-                // CraftBukkit - bypass infinite items; <= 0 -> == 0
-                if (itemstack.count == 0) {
-                    itemstack.a(this);
-                    this.R();
-                }
-            }
+            int j = 0;
+            int k = 0;
 
             if (entity instanceof EntityLiving) {
-                if (entity.isAlive()) {
-                    this.a((EntityLiving) entity, true);
-                }
-
-                this.a(StatisticList.w, i);
-                int l = EnchantmentManager.getFireAspectEnchantmentLevel(this.inventory, (EntityLiving) entity);
-
-                if (l > 0) {
-                    // CraftBukkit start - raise a combust event when somebody hits with a fire enchanted item
-                    EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), l * 4);
-                    Bukkit.getPluginManager().callEvent(combustEvent);
-
-                    if (!combustEvent.isCancelled()) {
-                        entity.setOnFire(combustEvent.getDuration());
-                    }
-                    // CraftBukkit end
-                }
+                k = EnchantmentManager.a(this.inventory, (EntityLiving) entity);
+                j += EnchantmentManager.getKnockbackEnchantmentLevel(this.inventory, (EntityLiving) entity);
             }
 
-            this.c(0.3F);
+            if (this.isSprinting()) {
+                ++j;
+            }
+
+            if (i > 0 || k > 0) {
+                boolean flag = this.fallDistance > 0.0F && !this.onGround && !this.t() && !this.aT() && !this.hasEffect(MobEffectList.BLINDNESS) && this.vehicle == null && entity instanceof EntityLiving;
+
+                if (flag) {
+                    i += this.random.nextInt(i / 2 + 2);
+                }
+
+                // CraftBukkit start - Don't call the event when the entity is human since it will be called with damageEntity
+                if ((entity instanceof EntityLiving || entity instanceof EntityComplexPart || entity instanceof EntityEnderCrystal) && !(entity instanceof EntityHuman)) {
+                    org.bukkit.entity.Entity damager = this.getBukkitEntity();
+                    org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity();
+
+                    EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, i);
+                    Bukkit.getPluginManager().callEvent(event);
+
+                    if (event.isCancelled() || event.getDamage() == 0) {
+                        return;
+                    }
+
+                    i = event.getDamage();
+                }
+                // CraftBukkit end
+
+                i += k;
+                boolean flag1 = entity.damageEntity(DamageSource.playerAttack(this), i);
+
+                // CraftBukkit start - Return when the damage fails so that the item will not lose durability
+                if (!flag1) {
+                    return;
+                }
+                // CraftBukkit end
+
+                if (flag1) {
+                    if (j > 0) {
+                        entity.b_((double) (-MathHelper.sin(this.yaw * 3.1415927F / 180.0F) * (float) j * 0.5F), 0.1D, (double) (MathHelper.cos(this.yaw * 3.1415927F / 180.0F) * (float) j * 0.5F));
+                        this.motX *= 0.6D;
+                        this.motZ *= 0.6D;
+                        this.setSprinting(false);
+                    }
+
+                    if (flag) {
+                        this.c(entity);
+                    }
+
+                    if (k > 0) {
+                        this.d(entity);
+                    }
+
+                    if (i >= 18) {
+                        this.a((Statistic) AchievementList.E);
+                    }
+
+                    this.g(entity);
+                }
+
+                ItemStack itemstack = this.T();
+
+                if (itemstack != null && entity instanceof EntityLiving) {
+                    itemstack.a((EntityLiving) entity, this);
+                    // CraftBukkit - bypass infinite items; <= 0 -> == 0
+                    if (itemstack.count == 0) {
+                        itemstack.a(this);
+                        this.U();
+                    }
+                }
+
+                if (entity instanceof EntityLiving) {
+                    if (entity.isAlive()) {
+                        this.a((EntityLiving) entity, true);
+                    }
+
+                    this.a(StatisticList.w, i);
+                    int l = EnchantmentManager.getFireAspectEnchantmentLevel(this.inventory, (EntityLiving) entity);
+
+                    if (l > 0) {
+                        // CraftBukkit start - raise a combust event when somebody hits with a fire enchanted item
+                        EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), l * 4);
+                        Bukkit.getPluginManager().callEvent(combustEvent);
+
+                        if (!combustEvent.isCancelled()) {
+                            entity.setOnFire(combustEvent.getDuration());
+                        }
+                        // CraftBukkit end
+                    }
+                }
+
+                this.c(0.3F);
+            }
         }
     }
 
@@ -888,7 +895,7 @@ public abstract class EntityHuman extends EntityLiving {
                 return EnumBedResult.OTHER_PROBLEM;
             }
 
-            if (this.world.worldProvider.d) {
+            if (!this.world.worldProvider.d()) {
                 return EnumBedResult.NOT_POSSIBLE_HERE;
             }
 
@@ -927,7 +934,7 @@ public abstract class EntityHuman extends EntityLiving {
         this.height = 0.2F;
         if (this.world.isLoaded(i, j, k)) {
             int l = this.world.getData(i, j, k);
-            int i1 = BlockBed.d(l);
+            int i1 = BlockBed.b(l);
             float f = 0.5F;
             float f1 = 0.5F;
 
@@ -990,7 +997,7 @@ public abstract class EntityHuman extends EntityLiving {
         if (this.fauxSleeping && !this.sleeping) return; // CraftBukkit - Can't leave bed if not in one!
 
         this.b(0.6F, 1.8F);
-        this.r_();
+        this.A();
         ChunkCoordinates chunkcoordinates = this.F;
         ChunkCoordinates chunkcoordinates1 = this.F;
 
@@ -1036,12 +1043,12 @@ public abstract class EntityHuman extends EntityLiving {
         }
     }
 
-    private boolean B() {
+    private boolean G() {
         return this.world.getTypeId(this.F.x, this.F.y, this.F.z) == Block.BED.id;
     }
 
     public static ChunkCoordinates getBed(World world, ChunkCoordinates chunkcoordinates) {
-        IChunkProvider ichunkprovider = world.p();
+        IChunkProvider ichunkprovider = world.q();
 
         ichunkprovider.getChunkAt(chunkcoordinates.x - 3 >> 4, chunkcoordinates.z - 3 >> 4);
         ichunkprovider.getChunkAt(chunkcoordinates.x + 3 >> 4, chunkcoordinates.z - 3 >> 4);
@@ -1085,8 +1092,8 @@ public abstract class EntityHuman extends EntityLiving {
 
     public void a(Statistic statistic, int i) {}
 
-    protected void o_() {
-        super.o_();
+    protected void ab() {
+        super.ab();
         this.a(StatisticList.u, 1);
         if (this.isSprinting()) {
             this.c(0.8F);
@@ -1125,13 +1132,13 @@ public abstract class EntityHuman extends EntityLiving {
                     this.a(StatisticList.q, i);
                     this.c(0.015F * (float) i * 0.01F);
                 }
-            } else if (this.aK()) {
+            } else if (this.aT()) {
                 i = Math.round(MathHelper.sqrt(d0 * d0 + d2 * d2) * 100.0F);
                 if (i > 0) {
                     this.a(StatisticList.m, i);
                     this.c(0.015F * (float) i * 0.01F);
                 }
-            } else if (this.r()) {
+            } else if (this.t()) {
                 if (d1 > 0.0D) {
                     this.a(StatisticList.o, (int) Math.round(d1 * 100.0D));
                 }
@@ -1163,7 +1170,7 @@ public abstract class EntityHuman extends EntityLiving {
                     this.a(StatisticList.r, i);
                     if (this.c == null) {
                         this.c = new ChunkCoordinates(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
-                    } else if (this.c.a(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) >= 1000.0D) {
+                    } else if (this.c.b(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) >= 1000.0D) {
                         this.a((Statistic) AchievementList.q, 1);
                     }
                 } else if (this.vehicle instanceof EntityBoat) {
@@ -1175,23 +1182,23 @@ public abstract class EntityHuman extends EntityLiving {
         }
     }
 
-    protected void b(float f) {
+    protected void a(float f) {
         if (!this.abilities.canFly) {
             if (f >= 2.0F) {
                 this.a(StatisticList.n, (int) Math.round((double) f * 100.0D));
             }
 
-            super.b(f);
+            super.a(f);
         }
     }
 
-    public void a(EntityLiving entityliving) {
+    public void c(EntityLiving entityliving) {
         if (entityliving instanceof EntityMonster) {
             this.a((Statistic) AchievementList.s);
         }
     }
 
-    public void Y() {
+    public void ac() {
         if (this.I > 0) {
             this.I = 10;
         } else {
@@ -1246,7 +1253,7 @@ public abstract class EntityHuman extends EntityLiving {
         return (flag || this.foodData.b()) && !this.abilities.isInvulnerable;
     }
 
-    public boolean ab() {
+    public boolean af() {
         return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth();
     }
 
@@ -1255,7 +1262,7 @@ public abstract class EntityHuman extends EntityLiving {
             this.d = itemstack;
             this.e = i;
             if (!this.world.isStatic) {
-                this.h(true);
+                this.i(true);
             }
         }
     }
@@ -1289,4 +1296,8 @@ public abstract class EntityHuman extends EntityLiving {
         this.exp = entityhuman.exp;
         this.q = entityhuman.q;
     }
+
+    protected boolean g_() {
+        return !this.abilities.isFlying;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
index 11549ad8c5..a7750ac0f3 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -8,10 +8,9 @@ import org.bukkit.event.player.PlayerPickupItemEvent;
 public class EntityItem extends Entity {
 
     public ItemStack itemStack;
-    private int e;
     public int age = 0;
     public int pickupDelay;
-    private int f = 5;
+    private int e = 5;
     public float d = (float) (Math.random() * 3.141592653589793D * 2.0D);
     private int lastTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit
 
@@ -47,8 +46,8 @@ public class EntityItem extends Entity {
 
     protected void b() {}
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         // CraftBukkit start
         int currentTick = (int) (System.currentTimeMillis() / 50);
         this.pickupDelay -= (currentTick - this.lastTick);
@@ -86,7 +85,6 @@ public class EntityItem extends Entity {
             this.motY *= -0.5D;
         }
 
-        ++this.e;
         ++this.age;
         if (this.age >= 6000) {
             // CraftBukkit start
@@ -99,7 +97,11 @@ public class EntityItem extends Entity {
         }
     }
 
-    public boolean i_() {
+    public void k() {
+        this.age = 4800;
+    }
+
+    public boolean h_() {
         return this.world.a(this.boundingBox, Material.WATER, this);
     }
 
@@ -108,9 +110,9 @@ public class EntityItem extends Entity {
     }
 
     public boolean damageEntity(DamageSource damagesource, int i) {
-        this.aM();
-        this.f -= i;
-        if (this.f <= 0) {
+        this.aV();
+        this.e -= i;
+        if (this.e <= 0) {
             this.die();
         }
 
@@ -118,14 +120,14 @@ public class EntityItem extends Entity {
     }
 
     public void b(NBTTagCompound nbttagcompound) {
-        nbttagcompound.setShort("Health", (short) ((byte) this.f));
+        nbttagcompound.setShort("Health", (short) ((byte) this.e));
         nbttagcompound.setShort("Age", (short) this.age);
         if (this.itemStack != null) // CraftBukkit - Nullchex!
         nbttagcompound.setCompound("Item", this.itemStack.save(new NBTTagCompound()));
     }
 
     public void a(NBTTagCompound nbttagcompound) {
-        this.f = nbttagcompound.getShort("Health") & 255;
+        this.e = nbttagcompound.getShort("Health") & 255;
         this.age = nbttagcompound.getShort("Age");
         NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item");
 
@@ -187,4 +189,8 @@ public class EntityItem extends Entity {
         if (this.itemStack == null) return LocaleI18n.get("item.unknown"); // CraftBukkit - nullcheck
         return LocaleI18n.get("item." + this.itemStack.k());
     }
+
+    public boolean k_() {
+        return false;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 6006724c35..abf1ec22e4 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -60,17 +60,26 @@ public abstract class EntityLiving extends Entity {
     public float aF;
     public EntityHuman killer = null; // CraftBukkit - prot to pub
     protected int lastDamageByPlayerTime = 0;
-    protected EntityLiving lastDamager = null;
+    public EntityLiving lastDamager = null; // CraftBukkit - priv to pub
+    private int c = 0;
+    private EntityLiving d = null;
+    public int aI = 0;
     public int aJ = 0;
-    public int aK = 0;
     public HashMap effects = new HashMap(); // CraftBukkit - protected -> public
-    private boolean b = true;
-    private int c;
+    private boolean e = true;
+    private int f;
     private ControllerLook lookController;
     private ControllerMove moveController;
     private ControllerJump jumpController;
+    private EntityAIBodyControl senses;
     private Navigation navigation;
     protected PathfinderGoalSelector goalSelector = new PathfinderGoalSelector();
+    protected PathfinderGoalSelector targetSelector = new PathfinderGoalSelector();
+    private EntityLiving l;
+    private EntitySenses m;
+    private float n;
+    private ChunkCoordinates o = new ChunkCoordinates(0, 0, 0);
+    private float p = -1.0F;
     protected int aN;
     protected double aO;
     protected double aP;
@@ -86,8 +95,8 @@ public abstract class EntityLiving extends Entity {
     protected boolean aZ = false;
     protected float ba = 0.0F;
     protected float bb = 0.7F;
-    private int h = 0;
-    private Entity i;
+    private int q = 0;
+    private Entity r;
     protected int bc = 0;
     public int expToDrop = 0; // CraftBukkit
     public int maxAirTicks = 300; // CraftBukkit
@@ -96,9 +105,11 @@ public abstract class EntityLiving extends Entity {
         super(world);
         this.bf = true;
         this.lookController = new ControllerLook(this);
-        this.moveController = new ControllerMove(this, this.bb);
+        this.moveController = new ControllerMove(this);
         this.jumpController = new ControllerJump(this);
-        this.navigation = new PathfinderNavigation(this, world);
+        this.senses = new EntityAIBodyControl(this);
+        this.navigation = new Navigation(this, world, 16.0F);
+        this.m = new EntitySenses(this);
         this.U = (float) (Math.random() + 1.0D) * 0.01F;
         this.setPosition(this.locX, this.locY, this.locZ);
         this.T = (float) Math.random() * 12398.0F;
@@ -119,35 +130,115 @@ public abstract class EntityLiving extends Entity {
         return this.jumpController;
     }
 
-    public Navigation ah() {
+    public Navigation ak() {
         return this.navigation;
     }
 
-    public Random ai() {
+    public EntitySenses al() {
+        return this.m;
+    }
+
+    public Random am() {
         return this.random;
     }
 
-    public EntityLiving aj() {
+    public EntityLiving an() {
         return this.lastDamager;
     }
 
-    public int ak() {
+    public EntityLiving ao() {
+        return this.d;
+    }
+
+    public void g(Entity entity) {
+        if (entity instanceof EntityLiving) {
+            this.d = (EntityLiving) entity;
+        }
+    }
+
+    public int ap() {
         return this.aV;
     }
 
-    protected void b() {
-        this.datawatcher.a(8, Integer.valueOf(this.c));
+    public float aq() {
+        return this.X;
     }
 
-    public boolean g(Entity entity) {
+    public float ar() {
+        return this.n;
+    }
+
+    public void d(float f) {
+        this.n = f;
+        this.e(f);
+    }
+
+    public boolean a(Entity entity) {
+        this.g(entity);
+        return false;
+    }
+
+    public EntityLiving as() {
+        return this.l;
+    }
+
+    public void b(EntityLiving entityliving) {
+        this.l = entityliving;
+    }
+
+    public boolean a(Class oclass) {
+        return EntityCreeper.class != oclass && EntityGhast.class != oclass;
+    }
+
+    public void z() {}
+
+    public boolean at() {
+        return this.e(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ));
+    }
+
+    public boolean e(int i, int j, int k) {
+        return this.p == -1.0F ? true : this.o.c(i, j, k) < this.p * this.p;
+    }
+
+    public void b(int i, int j, int k, int l) {
+        this.o.a(i, j, k);
+        this.p = (float) l;
+    }
+
+    public ChunkCoordinates au() {
+        return this.o;
+    }
+
+    public float av() {
+        return this.p;
+    }
+
+    public void aw() {
+        this.p = -1.0F;
+    }
+
+    public boolean ax() {
+        return this.p != -1.0F;
+    }
+
+    public void a(EntityLiving entityliving) {
+        this.lastDamager = entityliving;
+        this.c = this.lastDamager != null ? 60 : 0;
+    }
+
+    protected void b() {
+        this.datawatcher.a(8, Integer.valueOf(this.f));
+    }
+
+    public boolean h(Entity entity) {
         return this.world.a(Vec3D.create(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ), Vec3D.create(entity.locX, entity.locY + (double) entity.getHeadHeight(), entity.locZ)) == null;
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return !this.dead;
     }
 
-    public boolean f_() {
+    public boolean e_() {
         return !this.dead;
     }
 
@@ -155,25 +246,25 @@ public abstract class EntityLiving extends Entity {
         return this.length * 0.85F;
     }
 
-    public int h() {
+    public int m() {
         return 80;
     }
 
-    public void al() {
-        String s = this.c_();
+    public void ay() {
+        String s = this.i();
 
         if (s != null) {
-            this.world.makeSound(this, s, this.o(), this.v());
+            this.world.makeSound(this, s, this.p(), this.A());
         }
     }
 
-    public void am() {
+    public void az() {
         this.an = this.ao;
-        super.am();
+        super.az();
         // MethodProfiler.a("mobBaseTick"); // CraftBukkit - not in production code
         if (this.random.nextInt(1000) < this.a++) {
-            this.a = -this.h();
-            this.al();
+            this.a = -this.m();
+            this.ay();
         }
 
         // CraftBukkit start - don't inline the damage, perform it with an event
@@ -191,8 +282,8 @@ public abstract class EntityLiving extends Entity {
             this.extinguish();
         }
 
-        if (this.isAlive() && this.a(Material.WATER) && !this.f() && !this.effects.containsKey(Integer.valueOf(MobEffectList.WATER_BREATHING.id))) {
-            this.setAirTicks(this.f(this.getAirTicks()));
+        if (this.isAlive() && this.a(Material.WATER) && !this.f_() && !this.effects.containsKey(Integer.valueOf(MobEffectList.WATER_BREATHING.id))) {
+            this.setAirTicks(this.b_(this.getAirTicks()));
             if (this.getAirTicks() == -20) {
                 this.setAirTicks(0);
 
@@ -237,7 +328,7 @@ public abstract class EntityLiving extends Entity {
         }
 
         if (this.health <= 0) {
-            this.an();
+            this.aA();
         }
 
         if (this.lastDamageByPlayerTime > 0) {
@@ -246,7 +337,21 @@ public abstract class EntityLiving extends Entity {
             this.killer = null;
         }
 
-        this.aB();
+        if (this.d != null && !this.d.isAlive()) {
+            this.d = null;
+        }
+
+        if (this.lastDamager != null) {
+            if (!this.lastDamager.isAlive()) {
+                this.a((EntityLiving) null);
+            } else if (this.c > 0) {
+                --this.c;
+            } else {
+                this.a((EntityLiving) null);
+            }
+        }
+
+        this.aJ();
         this.ac = this.ab;
         this.W = this.V;
         this.Y = this.X;
@@ -267,7 +372,7 @@ public abstract class EntityLiving extends Entity {
     }
     // CraftBukkit end
 
-    protected void an() {
+    protected void aA() {
         ++this.deathTicks;
         if (this.deathTicks >= 20 && !this.dead) { // CraftBukkit - (this.deathTicks == 20) -> (this.deathTicks >= 20 && !this.dead).
             int i;
@@ -282,7 +387,7 @@ public abstract class EntityLiving extends Entity {
             }
             // CraftBukkit end
 
-            this.ay();
+            this.aG();
             this.die();
 
             for (i = 0; i < 20; ++i) {
@@ -295,7 +400,7 @@ public abstract class EntityLiving extends Entity {
         }
     }
 
-    protected int f(int i) {
+    protected int b_(int i) {
         return i - 1;
     }
 
@@ -307,7 +412,7 @@ public abstract class EntityLiving extends Entity {
         return false;
     }
 
-    public void ao() {
+    public void aB() {
         for (int i = 0; i < 20; ++i) {
             double d0 = this.random.nextGaussian() * 0.02D;
             double d1 = this.random.nextGaussian() * 0.02D;
@@ -318,27 +423,27 @@ public abstract class EntityLiving extends Entity {
         }
     }
 
-    public void N() {
-        super.N();
+    public void Q() {
+        super.Q();
         this.Z = this.aa;
         this.aa = 0.0F;
         this.fallDistance = 0.0F;
     }
 
-    public void y_() {
-        super.y_();
-        if (this.aJ > 0) {
-            if (this.aK <= 0) {
-                this.aK = 60;
+    public void G_() {
+        super.G_();
+        if (this.aI > 0) {
+            if (this.aJ <= 0) {
+                this.aJ = 60;
             }
 
-            --this.aK;
-            if (this.aK <= 0) {
-                --this.aJ;
+            --this.aJ;
+            if (this.aJ <= 0) {
+                --this.aI;
             }
         }
 
-        this.d();
+        this.e();
         double d0 = this.locX - this.lastX;
         double d1 = this.locZ - this.lastZ;
         float f = MathHelper.sqrt(d0 * d0 + d1 * d1);
@@ -364,46 +469,49 @@ public abstract class EntityLiving extends Entity {
         }
 
         this.aa += (f3 - this.aa) * 0.3F;
+        if (this.c_()) {
+            this.senses.a();
+        } else {
+            float f4;
 
-        float f4;
+            for (f4 = f1 - this.V; f4 < -180.0F; f4 += 360.0F) {
+                ;
+            }
 
-        for (f4 = f1 - this.V; f4 < -180.0F; f4 += 360.0F) {
-            ;
-        }
+            while (f4 >= 180.0F) {
+                f4 -= 360.0F;
+            }
 
-        while (f4 >= 180.0F) {
-            f4 -= 360.0F;
-        }
+            this.V += f4 * 0.3F;
 
-        this.V += f4 * 0.3F;
+            float f5;
 
-        float f5;
+            for (f5 = this.yaw - this.V; f5 < -180.0F; f5 += 360.0F) {
+                ;
+            }
 
-        for (f5 = this.yaw - this.V; f5 < -180.0F; f5 += 360.0F) {
-            ;
-        }
+            while (f5 >= 180.0F) {
+                f5 -= 360.0F;
+            }
 
-        while (f5 >= 180.0F) {
-            f5 -= 360.0F;
-        }
+            boolean flag = f5 < -90.0F || f5 >= 90.0F;
 
-        boolean flag = f5 < -90.0F || f5 >= 90.0F;
+            if (f5 < -75.0F) {
+                f5 = -75.0F;
+            }
 
-        if (f5 < -75.0F) {
-            f5 = -75.0F;
-        }
+            if (f5 >= 75.0F) {
+                f5 = 75.0F;
+            }
 
-        if (f5 >= 75.0F) {
-            f5 = 75.0F;
-        }
+            this.V = this.yaw - f5;
+            if (f5 * f5 > 2500.0F) {
+                this.V += f5 * 0.2F;
+            }
 
-        this.V = this.yaw - f5;
-        if (f5 * f5 > 2500.0F) {
-            this.V += f5 * 0.2F;
-        }
-
-        if (flag) {
-            f2 *= -1.0F;
+            if (flag) {
+                f2 *= -1.0F;
+            }
         }
 
         while (this.yaw - this.lastYaw < -180.0F) {
@@ -430,6 +538,14 @@ public abstract class EntityLiving extends Entity {
             this.lastPitch += 360.0F;
         }
 
+        while (this.X - this.Y < -180.0F) {
+            this.Y -= 360.0F;
+        }
+
+        while (this.X - this.Y >= 180.0F) {
+            this.Y += 360.0F;
+        }
+
         this.ab += f2;
     }
 
@@ -506,6 +622,10 @@ public abstract class EntityLiving extends Entity {
                 Entity entity = damagesource.getEntity();
 
                 if (entity != null) {
+                    if (entity instanceof EntityLiving) {
+                        this.a((EntityLiving) entity);
+                    }
+
                     if (entity instanceof EntityHuman) {
                         this.lastDamageByPlayerTime = 60;
                         this.killer = (EntityHuman) entity;
@@ -521,7 +641,7 @@ public abstract class EntityLiving extends Entity {
 
                 if (flag) {
                     this.world.broadcastEntityEffect(this, (byte) 2);
-                    this.aM();
+                    this.aV();
                     if (entity != null) {
                         double d0 = entity.locX - this.locX;
 
@@ -540,12 +660,12 @@ public abstract class EntityLiving extends Entity {
 
                 if (this.health <= 0) {
                     if (flag) {
-                        this.world.makeSound(this, this.n(), this.o(), this.v());
+                        this.world.makeSound(this, this.k(), this.p(), this.A());
                     }
 
                     this.die(damagesource);
                 } else if (flag) {
-                    this.world.makeSound(this, this.m(), this.o(), this.v());
+                    this.world.makeSound(this, this.j(), this.p(), this.A());
                 }
 
                 return true;
@@ -553,22 +673,22 @@ public abstract class EntityLiving extends Entity {
         }
     }
 
-    private float v() {
+    private float A() {
         return this.isBaby() ? (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.5F : (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F;
     }
 
-    public int P() {
+    public int S() {
         return 0;
     }
 
-    protected void g(int i) {}
+    protected void f(int i) {}
 
     protected int d(DamageSource damagesource, int i) {
         if (!damagesource.ignoresArmor()) {
-            int j = 25 - this.P();
+            int j = 25 - this.S();
             int k = i * j + this.ar;
 
-            this.g(i);
+            this.f(i);
             i = k / 25;
             this.ar = k % 25;
         }
@@ -595,19 +715,19 @@ public abstract class EntityLiving extends Entity {
         this.health -= i;
     }
 
-    protected float o() {
+    protected float p() {
         return 1.0F;
     }
 
-    protected String c_() {
+    protected String i() {
         return null;
     }
 
-    protected String m() {
+    protected String j() {
         return "damage.hurtflesh";
     }
 
-    protected String n() {
+    protected String k() {
         return "damage.hurtflesh";
     }
 
@@ -635,7 +755,7 @@ public abstract class EntityLiving extends Entity {
         }
 
         if (entity != null) {
-            entity.a(this);
+            entity.c(this);
         }
 
         this.az = true;
@@ -648,12 +768,21 @@ public abstract class EntityLiving extends Entity {
 
             if (!this.isBaby()) {
                 this.dropDeathLoot(this.lastDamageByPlayerTime > 0, i);
+                if (this.lastDamageByPlayerTime > 0) {
+                    int j = this.random.nextInt(200) - i;
+
+                    if (j < 5) {
+                        this.b(j <= 0 ? 1 : 0);
+                    }
+                }
             }
         }
 
         this.world.broadcastEntityEffect(this, (byte) 3);
     }
 
+    protected void b(int i) {}
+
     protected void dropDeathLoot(boolean flag, int i) {
         int j = this.getLootId();
 
@@ -680,8 +809,8 @@ public abstract class EntityLiving extends Entity {
         return 0;
     }
 
-    protected void b(float f) {
-        super.b(f);
+    protected void a(float f) {
+        super.a(f);
         int i = (int) Math.ceil((double) (f - 3.0F));
 
         if (i > 0) {
@@ -715,9 +844,9 @@ public abstract class EntityLiving extends Entity {
     public void a(float f, float f1) {
         double d0;
 
-        if (this.aK()) {
+        if (this.aT()) {
             d0 = this.locY;
-            this.a(f, f1, 0.02F);
+            this.a(f, f1, this.c_() ? 0.04F : 0.02F);
             this.move(this.motX, this.motY, this.motZ);
             this.motX *= 0.800000011920929D;
             this.motY *= 0.800000011920929D;
@@ -726,7 +855,7 @@ public abstract class EntityLiving extends Entity {
             if (this.positionChanged && this.d(this.motX, this.motY + 0.6000000238418579D - this.locY + d0, this.motZ)) {
                 this.motY = 0.30000001192092896D;
             }
-        } else if (this.aL()) {
+        } else if (this.aU()) {
             d0 = this.locY;
             this.a(f, f1, 0.02F);
             this.move(this.motX, this.motY, this.motZ);
@@ -750,7 +879,19 @@ public abstract class EntityLiving extends Entity {
             }
 
             float f3 = 0.16277136F / (f2 * f2 * f2);
-            float f4 = this.onGround ? this.al * f3 : this.am;
+            float f4;
+
+            if (this.onGround) {
+                if (this.c_()) {
+                    f4 = this.ar();
+                } else {
+                    f4 = this.al;
+                }
+
+                f4 *= f3;
+            } else {
+                f4 = this.am;
+            }
 
             this.a(f, f1, f4);
             f2 = 0.91F;
@@ -763,7 +904,7 @@ public abstract class EntityLiving extends Entity {
                 }
             }
 
-            if (this.r()) {
+            if (this.t()) {
                 float f5 = 0.15F;
 
                 if (this.motX < (double) (-f5)) {
@@ -787,13 +928,15 @@ public abstract class EntityLiving extends Entity {
                     this.motY = -0.15D;
                 }
 
-                if (this.isSneaking() && this.motY < 0.0D) {
+                boolean flag = this.isSneaking() && this instanceof EntityHuman;
+
+                if (flag && this.motY < 0.0D) {
                     this.motY = 0.0D;
                 }
             }
 
             this.move(this.motX, this.motY, this.motZ);
-            if (this.positionChanged && this.r()) {
+            if (this.positionChanged && this.t()) {
                 this.motY = 0.2D;
             }
 
@@ -816,12 +959,13 @@ public abstract class EntityLiving extends Entity {
         this.aF += this.aE;
     }
 
-    public boolean r() {
+    public boolean t() {
         int i = MathHelper.floor(this.locX);
         int j = MathHelper.floor(this.boundingBox.b);
         int k = MathHelper.floor(this.locZ);
+        int l = this.world.getTypeId(i, j, k);
 
-        return this.world.getTypeId(i, j, k) == Block.LADDER.id;
+        return l == Block.LADDER.id || l == Block.VINE.id;
     }
 
     public void b(NBTTagCompound nbttagcompound) {
@@ -875,25 +1019,21 @@ public abstract class EntityLiving extends Entity {
         return !this.dead && this.health > 0;
     }
 
-    public boolean f() {
+    public boolean f_() {
         return false;
     }
 
-    public void d(float f) {
+    public void e(float f) {
         this.aX = f;
     }
 
-    public void e(boolean flag) {
+    public void f(boolean flag) {
         this.aZ = flag;
     }
 
-    public float ar() {
-        return this.bb;
-    }
-
-    public void d() {
-        if (this.h > 0) {
-            --this.h;
+    public void e() {
+        if (this.q > 0) {
+            --this.q;
         }
 
         if (this.aN > 0) {
@@ -935,35 +1075,39 @@ public abstract class EntityLiving extends Entity {
         }
 
         // MethodProfiler.a("ai"); // CraftBukkit - not in production code
-        if (this.M()) {
+        if (this.P()) {
             this.aZ = false;
             this.aW = 0.0F;
             this.aX = 0.0F;
             this.aY = 0.0F;
-        } else if (this.at()) {
-            if (this.as()) {
-                this.av();
+        } else if (this.aE()) {
+            if (this.c_()) {
+                MethodProfiler.a("newAi");
+                this.z_();
+                MethodProfiler.a();
             } else {
-                this.m_();
+                MethodProfiler.a("oldAi");
+                this.d_();
+                MethodProfiler.a();
                 this.X = this.yaw;
             }
         }
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
-        boolean flag = this.aK();
-        boolean flag1 = this.aL();
+        boolean flag = this.aT();
+        boolean flag1 = this.aU();
 
         if (this.aZ) {
             if (flag) {
                 this.motY += 0.03999999910593033D;
             } else if (flag1) {
                 this.motY += 0.03999999910593033D;
-            } else if (this.onGround && this.h == 0) {
-                this.o_();
-                this.h = 10;
+            } else if (this.onGround && this.q == 0) {
+                this.ab();
+                this.q = 10;
             }
         } else {
-            this.h = 0;
+            this.q = 0;
         }
 
         this.aW *= 0.98F;
@@ -971,7 +1115,7 @@ public abstract class EntityLiving extends Entity {
         this.aY *= 0.9F;
         float f = this.al;
 
-        this.al *= this.G();
+        this.al *= this.D_();
         this.a(this.aW, this.aX);
         this.al = f;
         // MethodProfiler.a("push"); // CraftBukkit - not in production code
@@ -981,7 +1125,7 @@ public abstract class EntityLiving extends Entity {
             for (int j = 0; j < list1.size(); ++j) {
                 Entity entity = (Entity) list1.get(j);
 
-                if (entity.f_()) {
+                if (entity.e_()) {
                     entity.collide(this);
                 }
             }
@@ -990,23 +1134,23 @@ public abstract class EntityLiving extends Entity {
         // MethodProfiler.a(); // CraftBukkit - not in production code
     }
 
-    protected boolean as() {
+    protected boolean c_() {
         return false;
     }
 
-    protected boolean at() {
+    protected boolean aE() {
         return !this.world.isStatic;
     }
 
-    protected boolean M() {
+    protected boolean P() {
         return this.health <= 0;
     }
 
-    public boolean L() {
+    public boolean O() {
         return false;
     }
 
-    protected void o_() {
+    protected void ab() {
         this.motY = 0.41999998688697815D;
         if (this.hasEffect(MobEffectList.JUMP)) {
             this.motY += (double) ((float) (this.getEffect(MobEffectList.JUMP).getAmplifier() + 1) * 0.1F);
@@ -1022,11 +1166,11 @@ public abstract class EntityLiving extends Entity {
         this.ce = true;
     }
 
-    protected boolean d_() {
+    protected boolean n() {
         return true;
     }
 
-    protected void au() {
+    protected void aF() {
         EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D);
 
         if (entityhuman != null) {
@@ -1035,11 +1179,11 @@ public abstract class EntityLiving extends Entity {
             double d2 = entityhuman.locZ - this.locZ;
             double d3 = d0 * d0 + d1 * d1 + d2 * d2;
 
-            if (this.d_() && d3 > 16384.0D) {
+            if (this.n() && d3 > 16384.0D) {
                 this.die();
             }
 
-            if (this.aV > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D && this.d_()) {
+            if (this.aV > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D && this.n()) {
                 this.die();
             } else if (d3 < 1024.0D) {
                 this.aV = 0;
@@ -1047,25 +1191,40 @@ public abstract class EntityLiving extends Entity {
         }
     }
 
-    protected void av() {
+    protected void z_() {
         ++this.aV;
-        this.au();
-        if (this.lastDamager != null && !this.lastDamager.isAlive()) {
-            this.lastDamager = null;
-        }
-
+        //MethodProfiler.a("checkDespawn"); // CraftBukkit - not in production code
+        this.aF();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
+        //MethodProfiler.a("sensing"); // CraftBukkit - not in production code
+        this.m.a();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
+        //MethodProfiler.a("targetSelector"); // CraftBukkit - not in production code
+        this.targetSelector.a();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
+        //MethodProfiler.a("goalSelector"); // CraftBukkit - not in production code
         this.goalSelector.a();
-        this.navigation.a();
-        this.moveController.a();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
+        //MethodProfiler.a("navigation"); // CraftBukkit - not in production code
+        this.navigation.d();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
+        //MethodProfiler.a("mob tick"); // CraftBukkit - not in production code
+        this.g();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
+        //MethodProfiler.a("controls"); // CraftBukkit - not in production code
+        this.moveController.c();
         this.lookController.a();
         this.jumpController.b();
+        //MethodProfiler.a(); // CraftBukkit - not in production code
     }
 
-    protected void m_() {
+    protected void g() {}
+
+    protected void d_() {
         ++this.aV;
         EntityHuman entityhuman = this.world.findNearbyPlayer(this, -1.0D);
 
-        this.au();
+        this.aF();
         this.aW = 0.0F;
         this.aX = 0.0F;
         float f = 8.0F;
@@ -1073,17 +1232,17 @@ public abstract class EntityLiving extends Entity {
         if (this.random.nextFloat() < 0.02F) {
             entityhuman = this.world.findNearbyPlayer(this, (double) f);
             if (entityhuman != null) {
-                this.i = entityhuman;
+                this.r = entityhuman;
                 this.bc = 10 + this.random.nextInt(20);
             } else {
                 this.aY = (this.random.nextFloat() - 0.5F) * 20.0F;
             }
         }
 
-        if (this.i != null) {
-            this.a(this.i, 10.0F, (float) this.x());
-            if (this.bc-- <= 0 || this.i.dead || this.i.i(this) > (double) (f * f)) {
-                this.i = null;
+        if (this.r != null) {
+            this.a(this.r, 10.0F, (float) this.C());
+            if (this.bc-- <= 0 || this.r.dead || this.r.j(this) > (double) (f * f)) {
+                this.r = null;
             }
         } else {
             if (this.random.nextFloat() < 0.05F) {
@@ -1094,15 +1253,15 @@ public abstract class EntityLiving extends Entity {
             this.pitch = this.ba;
         }
 
-        boolean flag = this.aK();
-        boolean flag1 = this.aL();
+        boolean flag = this.aT();
+        boolean flag1 = this.aU();
 
         if (flag || flag1) {
             this.aZ = this.random.nextFloat() < 0.8F;
         }
     }
 
-    public int x() {
+    public int C() {
         return 40;
     }
 
@@ -1127,14 +1286,6 @@ public abstract class EntityLiving extends Entity {
         this.yaw = this.b(this.yaw, f2, f);
     }
 
-    public boolean aw() {
-        return this.i != null;
-    }
-
-    public Entity ax() {
-        return this.i;
-    }
-
     private float b(float f, float f1, float f2) {
         float f3;
 
@@ -1157,13 +1308,13 @@ public abstract class EntityLiving extends Entity {
         return f + f3;
     }
 
-    public void ay() {}
+    public void aG() {}
 
     public boolean canSpawn() {
         return this.world.containsEntity(this.boundingBox) && this.world.getCubes(this, this.boundingBox).size() == 0 && !this.world.containsLiquid(this.boundingBox);
     }
 
-    protected void az() {
+    protected void aH() {
         // CraftBukkit start
         EntityDamageByBlockEvent event = new EntityDamageByBlockEvent(null, this.getBukkitEntity(), EntityDamageEvent.DamageCause.VOID, 4);
         this.world.getServer().getPluginManager().callEvent(event);
@@ -1176,11 +1327,11 @@ public abstract class EntityLiving extends Entity {
         // CraftBukkit end
     }
 
-    public Vec3D aA() {
-        return this.e(1.0F);
+    public Vec3D aI() {
+        return this.f(1.0F);
     }
 
-    public Vec3D e(float f) {
+    public Vec3D f(float f) {
         float f1;
         float f2;
         float f3;
@@ -1204,7 +1355,7 @@ public abstract class EntityLiving extends Entity {
         }
     }
 
-    public int p() {
+    public int q() {
         return 4;
     }
 
@@ -1212,7 +1363,7 @@ public abstract class EntityLiving extends Entity {
         return false;
     }
 
-    protected void aB() {
+    protected void aJ() {
         Iterator iterator = this.effects.keySet().iterator();
 
         while (iterator.hasNext()) {
@@ -1227,7 +1378,7 @@ public abstract class EntityLiving extends Entity {
 
         int i;
 
-        if (this.b) {
+        if (this.e) {
             if (!this.world.isStatic) {
                 if (!this.effects.isEmpty()) {
                     i = PotionBrewer.a(this.effects.values());
@@ -1237,7 +1388,7 @@ public abstract class EntityLiving extends Entity {
                 }
             }
 
-            this.b = false;
+            this.e = false;
         }
 
         if (this.random.nextBoolean()) {
@@ -1252,7 +1403,7 @@ public abstract class EntityLiving extends Entity {
         }
     }
 
-    public void aC() {
+    public void aK() {
         Iterator iterator = this.effects.keySet().iterator();
 
         while (iterator.hasNext()) {
@@ -1302,23 +1453,23 @@ public abstract class EntityLiving extends Entity {
         return true;
     }
 
-    public boolean aE() {
+    public boolean aM() {
         return this.getMonsterType() == MonsterType.UNDEAD;
     }
 
     protected void b(MobEffect mobeffect) {
-        this.b = true;
+        this.e = true;
     }
 
     protected void c(MobEffect mobeffect) {
-        this.b = true;
+        this.e = true;
     }
 
     protected void d(MobEffect mobeffect) {
-        this.b = true;
+        this.e = true;
     }
 
-    protected float G() {
+    protected float D_() {
         float f = 1.0F;
 
         if (this.hasEffect(MobEffectList.FASTER_MOVEMENT)) {
diff --git a/src/main/java/net/minecraft/server/EntityMagmaCube.java b/src/main/java/net/minecraft/server/EntityMagmaCube.java
index 06183ac380..7223451894 100644
--- a/src/main/java/net/minecraft/server/EntityMagmaCube.java
+++ b/src/main/java/net/minecraft/server/EntityMagmaCube.java
@@ -16,19 +16,19 @@ public class EntityMagmaCube extends EntitySlime {
         return this.world.difficulty > 0 && this.world.containsEntity(this.boundingBox) && this.world.getCubes(this, this.boundingBox).size() == 0 && !this.world.containsLiquid(this.boundingBox);
     }
 
-    public int P() {
+    public int S() {
         return this.getSize() * 3;
     }
 
-    public float a(float f) {
+    public float b(float f) {
         return 1.0F;
     }
 
-    protected String v() {
+    protected String A() {
         return "flame";
     }
 
-    protected EntitySlime z() {
+    protected EntitySlime D() {
         return new EntityMagmaCube(this.world);
     }
 
@@ -59,46 +59,46 @@ public class EntityMagmaCube extends EntitySlime {
         return false;
     }
 
-    protected int B() {
-        return super.B() * 4;
+    protected int E() {
+        return super.E() * 4;
     }
 
-    protected void C() {
+    protected void F() {
         this.a *= 0.9F;
     }
 
-    protected void o_() {
+    protected void ab() {
         this.motY = (double) (0.42F + (float) this.getSize() * 0.1F);
         this.ce = true;
     }
 
-    protected void b(float f) {}
+    protected void a(float f) {}
 
-    protected boolean D() {
+    protected boolean G() {
         return true;
     }
 
-    protected int E() {
-        return super.E() + 2;
+    protected int H() {
+        return super.H() + 2;
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.slime";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.slime";
     }
 
-    protected String F() {
+    protected String J() {
         return this.getSize() > 1 ? "mob.magmacube.big" : "mob.magmacube.small";
     }
 
-    public boolean aL() {
+    public boolean aU() {
         return false;
     }
 
-    protected boolean H() {
+    protected boolean K() {
         return true;
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityMinecart.java b/src/main/java/net/minecraft/server/EntityMinecart.java
index ff59a209de..1e2c9eae84 100644
--- a/src/main/java/net/minecraft/server/EntityMinecart.java
+++ b/src/main/java/net/minecraft/server/EntityMinecart.java
@@ -90,15 +90,15 @@ public class EntityMinecart extends Entity implements IInventory {
         this.datawatcher.a(19, new Integer(0));
     }
 
-    public AxisAlignedBB a_(Entity entity) {
+    public AxisAlignedBB b_(Entity entity) {
         return entity.boundingBox;
     }
 
-    public AxisAlignedBB h_() {
+    public AxisAlignedBB h() {
         return null;
     }
 
-    public boolean f_() {
+    public boolean e_() {
         return true;
     }
 
@@ -116,7 +116,7 @@ public class EntityMinecart extends Entity implements IInventory {
         this.world.getServer().getPluginManager().callEvent(new VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit
     }
 
-    public double q() {
+    public double x_() {
         return (double) this.length * 0.0D - 0.30000001192092896D;
     }
 
@@ -136,9 +136,9 @@ public class EntityMinecart extends Entity implements IInventory {
             i = event.getDamage();
             // CraftBukkit end
 
-            this.d(-this.m());
-            this.c(10);
-            this.aM();
+            this.e(-this.n());
+            this.d(10);
+            this.aV();
             this.setDamage(this.getDamage() + i * 10);
             if (this.getDamage() > 40) {
                 if (this.passenger != null) {
@@ -200,7 +200,7 @@ public class EntityMinecart extends Entity implements IInventory {
         }
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return !this.dead;
     }
 
@@ -236,7 +236,7 @@ public class EntityMinecart extends Entity implements IInventory {
         super.die();
     }
 
-    public void y_() {
+    public void G_() {
         // CraftBukkit start
         double prevX = this.locX;
         double prevY = this.locY;
@@ -245,15 +245,15 @@ public class EntityMinecart extends Entity implements IInventory {
         float prevPitch = this.pitch;
         // CraftBukkit end
 
-        if (this.l() > 0) {
-            this.c(this.l() - 1);
+        if (this.m() > 0) {
+            this.d(this.m() - 1);
         }
 
         if (this.getDamage() > 0) {
             this.setDamage(this.getDamage() - 1);
         }
 
-        if (this.j() && this.random.nextInt(4) == 0) {
+        if (this.k() && this.random.nextInt(4) == 0) {
             this.world.a("largesmoke", this.locX, this.locY + 0.8D, this.locZ, 0.0D, 0.0D, 0.0D);
         }
 
@@ -598,7 +598,7 @@ public class EntityMinecart extends Entity implements IInventory {
                 for (int l1 = 0; l1 < list.size(); ++l1) {
                     Entity entity = (Entity) list.get(l1);
 
-                    if (entity != this.passenger && entity.f_() && entity instanceof EntityMinecart) {
+                    if (entity != this.passenger && entity.e_() && entity instanceof EntityMinecart) {
                         entity.collide(this);
                     }
                 }
@@ -851,6 +851,17 @@ public class EntityMinecart extends Entity implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         this.items[i] = itemstack;
         if (itemstack != null && itemstack.count > this.getMaxStackSize()) {
@@ -859,7 +870,7 @@ public class EntityMinecart extends Entity implements IInventory {
     }
 
     public String getName() {
-        return "Minecart";
+        return "container.minecart";
     }
 
     public int getMaxStackSize() {
@@ -900,10 +911,10 @@ public class EntityMinecart extends Entity implements IInventory {
     }
 
     public boolean a(EntityHuman entityhuman) {
-        return this.dead ? false : entityhuman.i(this) <= 64.0D;
+        return this.dead ? false : entityhuman.j(this) <= 64.0D;
     }
 
-    protected boolean j() {
+    protected boolean k() {
         return (this.datawatcher.getByte(16) & 1) != 0;
     }
 
@@ -927,19 +938,19 @@ public class EntityMinecart extends Entity implements IInventory {
         return this.datawatcher.getInt(19);
     }
 
-    public void c(int i) {
+    public void d(int i) {
         this.datawatcher.watch(17, Integer.valueOf(i));
     }
 
-    public int l() {
+    public int m() {
         return this.datawatcher.getInt(17);
     }
 
-    public void d(int i) {
+    public void e(int i) {
         this.datawatcher.watch(18, Integer.valueOf(i));
     }
 
-    public int m() {
+    public int n() {
         return this.datawatcher.getInt(18);
     }
 
diff --git a/src/main/java/net/minecraft/server/EntityMonster.java b/src/main/java/net/minecraft/server/EntityMonster.java
index 61676bd4b0..a5881412be 100644
--- a/src/main/java/net/minecraft/server/EntityMonster.java
+++ b/src/main/java/net/minecraft/server/EntityMonster.java
@@ -17,18 +17,18 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
         this.aA = 5;
     }
 
-    public void d() {
-        float f = this.a(1.0F);
+    public void e() {
+        float f = this.b(1.0F);
 
         if (f > 0.5F) {
             this.aV += 2;
         }
 
-        super.d();
+        super.e();
     }
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         if (!this.world.isStatic && this.world.difficulty == 0) {
             this.die();
         }
@@ -37,7 +37,7 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
     protected Entity findTarget() {
         EntityHuman entityhuman = this.world.findNearbyVulnerablePlayer(this, 16.0D);
 
-        return entityhuman != null && this.g(entityhuman) ? entityhuman : null;
+        return entityhuman != null && this.h(entityhuman) ? entityhuman : null;
     }
 
     public boolean damageEntity(DamageSource damagesource, int i) {
@@ -73,7 +73,7 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
         }
     }
 
-    public boolean d(Entity entity) {
+    public boolean a(Entity entity) {
         int i = this.damage;
 
         if (this.hasEffect(MobEffectList.INCREASE_DAMAGE)) {
@@ -108,12 +108,12 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
     protected void a(Entity entity, float f) {
         if (this.attackTicks <= 0 && f < 2.0F && entity.boundingBox.e > this.boundingBox.b && entity.boundingBox.b < this.boundingBox.e) {
             this.attackTicks = 20;
-            this.d(entity);
+            this.a(entity);
         }
     }
 
     public float a(int i, int j, int k) {
-        return 0.5F - this.world.m(i, j, k);
+        return 0.5F - this.world.p(i, j, k);
     }
 
     public void b(NBTTagCompound nbttagcompound) {
@@ -124,7 +124,7 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
         super.a(nbttagcompound);
     }
 
-    protected boolean z() {
+    protected boolean D() {
         int i = MathHelper.floor(this.locX);
         int j = MathHelper.floor(this.boundingBox.b);
         int k = MathHelper.floor(this.locZ);
@@ -134,12 +134,12 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
         } else {
             int l = this.world.getLightLevel(i, j, k);
 
-            if (this.world.v()) {
-                int i1 = this.world.k;
+            if (this.world.w()) {
+                int i1 = this.world.f;
 
-                this.world.k = 10;
+                this.world.f = 10;
                 l = this.world.getLightLevel(i, j, k);
-                this.world.k = i1;
+                this.world.f = i1;
             }
 
             return l <= this.random.nextInt(8);
@@ -147,6 +147,6 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
     }
 
     public boolean canSpawn() {
-        return this.z() && super.canSpawn();
+        return this.D() && super.canSpawn();
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java
index e2322a874a..b3860ec9c8 100644
--- a/src/main/java/net/minecraft/server/EntityMushroomCow.java
+++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java
@@ -25,16 +25,18 @@ public class EntityMushroomCow extends EntityCow {
             // CraftBukkit end
 
             this.die();
-            EntityCow entitycow = new EntityCow(this.world);
-
-            entitycow.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch);
-            entitycow.setHealth(this.getHealth());
-            entitycow.V = this.V;
-            this.world.addEntity(entitycow);
             this.world.a("largeexplode", this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, 0.0D, 0.0D, 0.0D);
+            if (!this.world.isStatic) {
+                EntityCow entitycow = new EntityCow(this.world);
 
-            for (int i = 0; i < 5; ++i) {
-                this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + (double) this.length, this.locZ, new ItemStack(Block.RED_MUSHROOM)));
+                entitycow.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch);
+                entitycow.setHealth(this.getHealth());
+                entitycow.V = this.V;
+                this.world.addEntity(entitycow);
+
+                for (int i = 0; i < 5; ++i) {
+                    this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + (double) this.length, this.locZ, new ItemStack(Block.RED_MUSHROOM)));
+                }
             }
 
             return true;
@@ -43,7 +45,7 @@ public class EntityMushroomCow extends EntityCow {
         }
     }
 
-    protected EntityAnimal createChild(EntityAnimal entityanimal) {
+    public EntityAnimal createChild(EntityAnimal entityanimal) {
         return new EntityMushroomCow(this.world);
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityPainting.java b/src/main/java/net/minecraft/server/EntityPainting.java
index 7ddef03eb7..45b00fbb6c 100644
--- a/src/main/java/net/minecraft/server/EntityPainting.java
+++ b/src/main/java/net/minecraft/server/EntityPainting.java
@@ -120,7 +120,7 @@ public class EntityPainting extends Entity {
         return i == 32 ? 0.5F : (i == 64 ? 0.5F : 0.0F);
     }
 
-    public void y_() {
+    public void G_() {
         if (this.f++ == 100 && !this.world.isStatic) {
             this.f = 0;
             if (!this.survives()) {
@@ -207,7 +207,7 @@ public class EntityPainting extends Entity {
         }
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return true;
     }
 
@@ -235,7 +235,7 @@ public class EntityPainting extends Entity {
             // CraftBukkit end
 
             this.die();
-            this.aM();
+            this.aV();
             this.world.addEntity(new EntityItem(this.world, this.locX, this.locY, this.locZ, new ItemStack(Item.PAINTING)));
         }
 
diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java
index bf1f9669d9..d412595ac8 100644
--- a/src/main/java/net/minecraft/server/EntityPig.java
+++ b/src/main/java/net/minecraft/server/EntityPig.java
@@ -6,6 +6,21 @@ public class EntityPig extends EntityAnimal {
         super(world);
         this.texture = "/mob/pig.png";
         this.b(0.9F, 0.9F);
+        this.ak().a(true);
+        float f = 0.25F;
+
+        this.goalSelector.a(0, new PathfinderGoalFloat(this));
+        this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.38F));
+        this.goalSelector.a(2, new PathfinderGoalBreed(this, f));
+        this.goalSelector.a(3, new PathfinderGoalTempt(this, 0.25F, Item.WHEAT.id, false));
+        this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 0.28F));
+        this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, f));
+        this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
+        this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
+    }
+
+    public boolean c_() {
+        return true;
     }
 
     public int getMaxHealth() {
@@ -27,15 +42,15 @@ public class EntityPig extends EntityAnimal {
         this.setSaddle(nbttagcompound.getBoolean("Saddle"));
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.pig";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.pig";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.pigdeath";
     }
 
@@ -83,14 +98,14 @@ public class EntityPig extends EntityAnimal {
         }
     }
 
-    protected void b(float f) {
-        super.b(f);
+    protected void a(float f) {
+        super.a(f);
         if (f > 5.0F && this.passenger instanceof EntityHuman) {
             ((EntityHuman) this.passenger).a((Statistic) AchievementList.u);
         }
     }
 
-    protected EntityAnimal createChild(EntityAnimal entityanimal) {
+    public EntityAnimal createChild(EntityAnimal entityanimal) {
         return new EntityPig(this.world);
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java
index 43dbf8fb2e..0988afbcf8 100644
--- a/src/main/java/net/minecraft/server/EntityPigZombie.java
+++ b/src/main/java/net/minecraft/server/EntityPigZombie.java
@@ -23,17 +23,17 @@ public class EntityPigZombie extends EntityZombie {
         this.fireProof = true;
     }
 
-    protected boolean as() {
+    protected boolean c_() {
         return false;
     }
 
-    public void y_() {
+    public void G_() {
         this.bb = this.target != null ? 0.95F : 0.5F;
         if (this.soundDelay > 0 && --this.soundDelay == 0) {
-            this.world.makeSound(this, "mob.zombiepig.zpigangry", this.o() * 2.0F, ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 1.8F);
+            this.world.makeSound(this, "mob.zombiepig.zpigangry", this.p() * 2.0F, ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 1.8F);
         }
 
-        super.y_();
+        super.G_();
     }
 
     public boolean canSpawn() {
@@ -54,8 +54,8 @@ public class EntityPigZombie extends EntityZombie {
         return this.angerLevel == 0 ? null : super.findTarget();
     }
 
-    public void d() {
-        super.d();
+    public void e() {
+        super.e();
     }
 
     public boolean damageEntity(DamageSource damagesource, int i) {
@@ -70,17 +70,17 @@ public class EntityPigZombie extends EntityZombie {
                 if (entity1 instanceof EntityPigZombie) {
                     EntityPigZombie entitypigzombie = (EntityPigZombie) entity1;
 
-                    entitypigzombie.f(entity);
+                    entitypigzombie.e(entity);
                 }
             }
 
-            this.f(entity);
+            this.e(entity);
         }
 
         return super.damageEntity(damagesource, i);
     }
 
-    private void f(Entity entity) {
+    private void e(Entity entity) {
         // CraftBukkit start
         org.bukkit.entity.Entity bukkitTarget = entity == null ? null : entity.getBukkitEntity();
 
@@ -103,15 +103,15 @@ public class EntityPigZombie extends EntityZombie {
         this.soundDelay = this.random.nextInt(40);
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.zombiepig.zpig";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.zombiepig.zpighurt";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.zombiepig.zpigdeath";
     }
 
@@ -135,6 +135,25 @@ public class EntityPigZombie extends EntityZombie {
         // CraftBukkit end
     }
 
+    protected void b(int i) {
+        if (i > 0) {
+            ItemStack itemstack = new ItemStack(Item.GOLD_SWORD);
+
+            EnchantmentManager.a(this.random, itemstack, 5);
+            this.a(itemstack, 0.0F);
+        } else {
+            int j = this.random.nextInt(3);
+
+            if (j == 0) {
+                this.b(Item.GOLD_INGOT.id, 1);
+            } else if (j == 1) {
+                this.b(Item.GOLD_SWORD.id, 1);
+            } else if (j == 2) {
+                this.b(Item.GOLD_HELMET.id, 1);
+            }
+        }
+    }
+
     protected int getLootId() {
         return Item.ROTTEN_FLESH.id;
     }
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 6a9ae75cdd..90a154ef71 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -46,9 +46,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         int j = chunkcoordinates.z;
         int k = chunkcoordinates.y;
 
-        if (!world.worldProvider.f) {
+        if (!world.worldProvider.e) {
             i += this.random.nextInt(20) - 10;
-            k = world.f(i, j);
+            k = world.g(i, j);
             j += this.random.nextInt(20) - 10;
         }
 
@@ -127,7 +127,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         return this.ck;
     }
 
-    protected void r_() {
+    protected void A() {
         this.height = 0.0F;
     }
 
@@ -135,7 +135,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         return 1.62F;
     }
 
-    public void y_() {
+    public void G_() {
         this.itemInWorldManager.c();
         --this.invulnerableTicks;
         this.activeContainer.a();
@@ -216,7 +216,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         }
     }
 
-    protected boolean z() {
+    protected boolean C_() {
         return this.server.pvpMode;
     }
 
@@ -225,12 +225,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
     }
 
     public void a(boolean flag) {
-        super.y_();
+        super.G_();
 
         for (int i = 0; i < this.inventory.getSize(); ++i) {
             ItemStack itemstack = this.inventory.getItem(i);
 
-            if (itemstack != null && Item.byId[itemstack.id].n_() && this.netServerHandler.lowPriorityCount() <= 2) {
+            if (itemstack != null && Item.byId[itemstack.id].t_() && this.netServerHandler.lowPriorityCount() <= 2) {
                 Packet packet = ((ItemWorldMapBase) Item.byId[itemstack.id]).c(itemstack, this.world, this);
 
                 if (packet != null) {
@@ -241,6 +241,17 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
 
         if (flag && !this.chunkCoordIntPairQueue.isEmpty()) {
             ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) this.chunkCoordIntPairQueue.get(0);
+            double d0 = chunkcoordintpair.a(this);
+
+            for (int j = 0; j < this.chunkCoordIntPairQueue.size(); ++j) {
+                ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair) this.chunkCoordIntPairQueue.get(j);
+                double d1 = chunkcoordintpair1.a(this);
+
+                if (d1 < d0) {
+                    chunkcoordintpair = chunkcoordintpair1;
+                    d0 = d1;
+                }
+            }
 
             if (chunkcoordintpair != null) {
                 boolean flag1 = false;
@@ -253,12 +264,18 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
                 if (flag1) {
                     WorldServer worldserver = this.server.getWorldServer(this.dimension);
 
-                    this.chunkCoordIntPairQueue.remove(chunkcoordintpair);
-                    this.netServerHandler.sendPacket(new Packet51MapChunk(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, 16, worldserver.height, 16, worldserver));
-                    List list = worldserver.getTileEntities(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, worldserver.height, chunkcoordintpair.z * 16 + 16);
+                    if (worldserver.isLoaded(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)) {
+                        Chunk chunk = worldserver.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z);
 
-                    for (int j = 0; j < list.size(); ++j) {
-                        this.a((TileEntity) list.get(j));
+                        if (chunk.done) {
+                            this.chunkCoordIntPairQueue.remove(chunkcoordintpair);
+                            this.netServerHandler.sendPacket(new Packet51MapChunk(worldserver.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z), true, 0));
+                            List list = worldserver.getTileEntities(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 256, chunkcoordintpair.z * 16 + 16);
+
+                            for (int k = 0; k < list.size(); ++k) {
+                                this.a((TileEntity) list.get(k));
+                            }
+                        }
                     }
                 }
             }
@@ -359,7 +376,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
 
     private void a(TileEntity tileentity) {
         if (tileentity != null) {
-            Packet packet = tileentity.k();
+            Packet packet = tileentity.d();
 
             if (packet != null) {
                 this.netServerHandler.sendPacket(packet);
@@ -388,7 +405,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         this.activeContainer.a();
     }
 
-    public void s_() {
+    public void D() {
         if (!this.t) {
             this.u = -1;
             this.t = true;
@@ -398,7 +415,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         }
     }
 
-    public void B() {}
+    public void E() {}
 
     public EnumBedResult a(int i, int j, int k) {
         EnumBedResult enumbedresult = super.a(i, j, k);
@@ -563,7 +580,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
 
     public void closeInventory() {
         this.netServerHandler.sendPacket(new Packet101CloseWindow(this.activeContainer.windowId));
-        this.E();
+        this.H();
     }
 
     public void broadcastCarriedItem() {
@@ -572,7 +589,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         }
     }
 
-    public void E() {
+    public void H() {
         this.activeContainer.a((EntityHuman) this);
         this.activeContainer = this.defaultContainer;
     }
@@ -590,7 +607,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         }
     }
 
-    public void F() {
+    public void I() {
         if (this.vehicle != null) {
             this.mount(this.vehicle);
         }
@@ -604,7 +621,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         }
     }
 
-    public void t_() {
+    public void J() {
         this.cf = -99999999;
         this.lastSentExp = -1; // CraftBukkit - Added to reset
     }
@@ -616,9 +633,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
         this.netServerHandler.sendPacket(new Packet3Chat(s1));
     }
 
-    protected void H() {
+    protected void K() {
         this.netServerHandler.sendPacket(new Packet38EntityStatus(this.id, (byte) 9));
-        super.H();
+        super.K();
     }
 
     public void a(ItemStack itemstack, int i) {
diff --git a/src/main/java/net/minecraft/server/EntityPotion.java b/src/main/java/net/minecraft/server/EntityPotion.java
index 06addec80d..d581fa5b07 100644
--- a/src/main/java/net/minecraft/server/EntityPotion.java
+++ b/src/main/java/net/minecraft/server/EntityPotion.java
@@ -63,7 +63,7 @@ public class EntityPotion extends EntityProjectile {
 
                     while (iterator.hasNext()) {
                         Entity entity = (Entity) iterator.next();
-                        double d0 = this.i(entity);
+                        double d0 = this.j(entity);
 
                         if (d0 < 16.0D) {
                             double d1 = 1.0D - Math.sqrt(d0) / 4.0D;
diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java
index dbc55322d8..3362749342 100644
--- a/src/main/java/net/minecraft/server/EntityProjectile.java
+++ b/src/main/java/net/minecraft/server/EntityProjectile.java
@@ -82,11 +82,11 @@ public abstract class EntityProjectile extends Entity {
         this.h = 0;
     }
 
-    public void y_() {
+    public void G_() {
         this.bL = this.locX;
         this.bM = this.locY;
         this.bN = this.locZ;
-        super.y_();
+        super.G_();
         if (this.shake > 0) {
             --this.shake;
         }
@@ -131,7 +131,7 @@ public abstract class EntityProjectile extends Entity {
             for (int j = 0; j < list.size(); ++j) {
                 Entity entity1 = (Entity) list.get(j);
 
-                if (entity1.e_() && (entity1 != this.shooter || this.i >= 5)) {
+                if (entity1.o_() && (entity1 != this.shooter || this.i >= 5)) {
                     float f = 0.3F;
                     AxisAlignedBB axisalignedbb = entity1.boundingBox.grow((double) f, (double) f, (double) f);
                     MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
@@ -190,7 +190,7 @@ public abstract class EntityProjectile extends Entity {
         float f2 = 0.99F;
         float f3 = this.e();
 
-        if (this.aK()) {
+        if (this.aT()) {
             for (int k = 0; k < 4; ++k) {
                 float f4 = 0.25F;
 
diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java
index 85c86e8373..59f3eb9c10 100644
--- a/src/main/java/net/minecraft/server/EntitySheep.java
+++ b/src/main/java/net/minecraft/server/EntitySheep.java
@@ -12,11 +12,41 @@ public class EntitySheep extends EntityAnimal {
 
     public static final float[][] a = new float[][] { { 1.0F, 1.0F, 1.0F}, { 0.95F, 0.7F, 0.2F}, { 0.9F, 0.5F, 0.85F}, { 0.6F, 0.7F, 0.95F}, { 0.9F, 0.9F, 0.2F}, { 0.5F, 0.8F, 0.1F}, { 0.95F, 0.7F, 0.8F}, { 0.3F, 0.3F, 0.3F}, { 0.6F, 0.6F, 0.6F}, { 0.3F, 0.6F, 0.7F}, { 0.7F, 0.4F, 0.9F}, { 0.2F, 0.4F, 0.8F}, { 0.5F, 0.4F, 0.3F}, { 0.4F, 0.5F, 0.2F}, { 0.8F, 0.3F, 0.3F}, { 0.1F, 0.1F, 0.1F}};
     private int b;
+    private PathfinderGoalEatTile c = new PathfinderGoalEatTile(this);
 
     public EntitySheep(World world) {
         super(world);
         this.texture = "/mob/sheep.png";
         this.b(0.9F, 1.3F);
+        float f = 0.23F;
+
+        this.ak().a(true);
+        this.goalSelector.a(0, new PathfinderGoalFloat(this));
+        this.goalSelector.a(1, new PathfinderGoalPanic(this, 0.38F));
+        this.goalSelector.a(2, new PathfinderGoalBreed(this, f));
+        this.goalSelector.a(3, new PathfinderGoalTempt(this, 0.25F, Item.WHEAT.id, false));
+        this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 0.25F));
+        this.goalSelector.a(5, this.c);
+        this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, f));
+        this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
+        this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+    }
+
+    protected boolean c_() {
+        return true;
+    }
+
+    protected void z_() {
+        this.b = this.c.f();
+        super.z_();
+    }
+
+    public void e() {
+        if (this.world.isStatic) {
+            this.b = Math.max(0, this.b - 1);
+        }
+
+        super.e();
     }
 
     public int getMaxHealth() {
@@ -44,86 +74,6 @@ public class EntitySheep extends EntityAnimal {
         return Block.WOOL.id;
     }
 
-    public void d() {
-        super.d();
-        if (this.b > 0) {
-            --this.b;
-        }
-    }
-
-    protected void o_() {
-        if (this.b <= 0) {
-            super.o_();
-        }
-    }
-
-    protected void m_() {
-        super.m_();
-        int i;
-        int j;
-        int k;
-
-        if (!this.E() && this.b <= 0 && (this.isBaby() && this.random.nextInt(50) == 0 || this.random.nextInt(1000) == 0)) {
-            i = MathHelper.floor(this.locX);
-            j = MathHelper.floor(this.locY);
-            k = MathHelper.floor(this.locZ);
-            if (this.world.getTypeId(i, j, k) == Block.LONG_GRASS.id && this.world.getData(i, j, k) == 1 || this.world.getTypeId(i, j - 1, k) == Block.GRASS.id) {
-                this.b = 40;
-                this.world.broadcastEntityEffect(this, (byte) 10);
-            }
-        } else if (this.b == 4) {
-            i = MathHelper.floor(this.locX);
-            j = MathHelper.floor(this.locY);
-            k = MathHelper.floor(this.locZ);
-            boolean flag = false;
-
-            if (this.world.getTypeId(i, j, k) == Block.LONG_GRASS.id) {
-                // CraftBukkit start
-                if (!CraftEventFactory.callEntityChangeBlockEvent(this.getBukkitEntity(), this.world.getWorld().getBlockAt(i, j, k), Material.AIR).isCancelled()) {
-                    this.world.triggerEffect(2001, i, j, k, Block.LONG_GRASS.id + 256);
-                    this.world.setTypeId(i, j, k, 0);
-                    flag = true;
-                }
-                // CraftBukkit end
-            } else if (this.world.getTypeId(i, j - 1, k) == Block.GRASS.id) {
-                // CraftBukkit start
-                if (!CraftEventFactory.callEntityChangeBlockEvent(this.getBukkitEntity(), this.world.getWorld().getBlockAt(i, j - 1, k), Material.DIRT).isCancelled()) {
-                    this.world.triggerEffect(2001, i, j - 1, k, Block.GRASS.id);
-                    this.world.setTypeId(i, j - 1, k, Block.DIRT.id);
-                    flag = true;
-                }
-                // CraftBukkit end
-            }
-
-            if (flag) {
-               // CraftBukkit start
-                if (!this.isBaby()) {
-                    org.bukkit.event.entity.SheepRegrowWoolEvent event = new org.bukkit.event.entity.SheepRegrowWoolEvent((Sheep) this.getBukkitEntity());
-                    this.world.getServer().getPluginManager().callEvent(event);
-
-                    if (!event.isCancelled()) {
-                        this.setSheared(false);
-                    }
-                }
-                // CraftBukkit end
-
-                if (this.isBaby()) {
-                    int l = this.getAge() + 1200;
-
-                    if (l > 0) {
-                        l = 0;
-                    }
-
-                    this.setAge(l);
-                }
-            }
-        }
-    }
-
-    protected boolean v() {
-        return this.b > 0;
-    }
-
     public boolean b(EntityHuman entityhuman) {
         ItemStack itemstack = entityhuman.inventory.getItemInHand();
 
@@ -168,15 +118,15 @@ public class EntitySheep extends EntityAnimal {
         this.setColor(nbttagcompound.getByte("Color"));
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.sheep";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.sheep";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.sheep";
     }
 
@@ -210,7 +160,7 @@ public class EntitySheep extends EntityAnimal {
         return i < 5 ? 15 : (i < 10 ? 7 : (i < 15 ? 8 : (i < 18 ? 12 : (random.nextInt(500) == 0 ? 6 : 0))));
     }
 
-    protected EntityAnimal createChild(EntityAnimal entityanimal) {
+    public EntityAnimal createChild(EntityAnimal entityanimal) {
         EntitySheep entitysheep = (EntitySheep) entityanimal;
         EntitySheep entitysheep1 = new EntitySheep(this.world);
 
@@ -222,4 +172,25 @@ public class EntitySheep extends EntityAnimal {
 
         return entitysheep1;
     }
+
+    public void z() {
+        // CraftBukkit start
+        org.bukkit.event.entity.SheepRegrowWoolEvent event = new org.bukkit.event.entity.SheepRegrowWoolEvent((Sheep) this.getBukkitEntity());
+        this.world.getServer().getPluginManager().callEvent(event);
+
+        if (!event.isCancelled()) {
+            this.setSheared(false);
+        }
+        // CraftBukkit end
+
+        if (this.isBaby()) {
+            int i = this.getAge() + 1200;
+
+            if (i > 0) {
+                i = 0;
+            }
+
+            this.setAge(i);
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/server/EntitySkeleton.java b/src/main/java/net/minecraft/server/EntitySkeleton.java
index 981aca475f..d054c93ae8 100644
--- a/src/main/java/net/minecraft/server/EntitySkeleton.java
+++ b/src/main/java/net/minecraft/server/EntitySkeleton.java
@@ -14,26 +14,52 @@ public class EntitySkeleton extends EntityMonster {
     public EntitySkeleton(World world) {
         super(world);
         this.texture = "/mob/skeleton.png";
+        this.bb = 0.25F;
+        this.goalSelector.a(1, new PathfinderGoalFloat(this));
+        this.goalSelector.a(2, new PathfinderGoalRestrictSun(this));
+        this.goalSelector.a(3, new PathfinderGoalFleeSun(this, this.bb));
+        this.goalSelector.a(4, new PathfinderGoalArrowAttack(this, this.bb, 1, 60));
+        this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, this.bb));
+        this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
+        this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this));
+        this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false));
+        this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, false));
+    }
+
+    public boolean c_() {
+        return true;
     }
 
     public int getMaxHealth() {
         return 20;
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.skeleton";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.skeletonhurt";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.skeletonhurt";
     }
 
-    public boolean damageEntity(DamageSource damagesource, int i) {
-        return super.damageEntity(damagesource, i);
+    public MonsterType getMonsterType() {
+        return MonsterType.UNDEAD;
+    }
+
+    public void e() {
+        if (this.world.e() && !this.world.isStatic) {
+            float f = this.b(1.0F);
+
+            if (f > 0.5F && this.world.isChunkLoaded(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
+                this.setOnFire(8);
+            }
+        }
+
+        super.e();
     }
 
     public void die(DamageSource damagesource) {
@@ -49,66 +75,6 @@ public class EntitySkeleton extends EntityMonster {
         }
     }
 
-    public void d() {
-        if (this.world.e() && !this.world.isStatic) {
-            float f = this.a(1.0F);
-
-            if (f > 0.5F && this.world.isChunkLoaded(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
-                // CraftBukkit start
-                EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8);
-                this.world.getServer().getPluginManager().callEvent(event);
-
-                if (!event.isCancelled()) {
-                    this.setOnFire(event.getDuration());
-                }
-                // CraftBukkit end
-            }
-        }
-
-        super.d();
-    }
-
-    protected void a(Entity entity, float f) {
-        if (f < 10.0F) {
-            double d0 = entity.locX - this.locX;
-            double d1 = entity.locZ - this.locZ;
-
-            if (this.attackTicks == 0) {
-                EntityArrow entityarrow = new EntityArrow(this.world, this, 1.0F);
-                double d2 = entity.locY + (double) entity.getHeadHeight() - 0.699999988079071D - entityarrow.locY;
-                float f1 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 0.2F;
-
-                // this.world.makeSound(this, "random.bow", 1.0F, 1.0F / (this.random.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - moved down
-                // this.world.addEntity(entityarrow); // CraftBukkit - moved down
-                entityarrow.shoot(d0, d2 + (double) f1, d1, 1.6F, 12.0F);
-                this.attackTicks = 60;
-
-                // CraftBukkit start
-                EntityShootBowEvent event = CraftEventFactory.callEntityShootBowEvent(this, null, entityarrow, 0.5F);
-                if (event.isCancelled()) {
-                    if (event.getProjectile() != null) {
-                        event.getProjectile().remove();
-                    }
-                } else if (event.getProjectile() == entityarrow.getBukkitEntity()) {
-                    world.addEntity(entityarrow);
-                }
-                this.world.makeSound(this, "random.bow", 1.0F, 1.0F / (this.random.nextFloat() * 0.4F + 0.8F));
-                // CraftBukkit end
-            }
-
-            this.yaw = (float) (Math.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
-            this.e = true;
-        }
-    }
-
-    public void b(NBTTagCompound nbttagcompound) {
-        super.b(nbttagcompound);
-    }
-
-    public void a(NBTTagCompound nbttagcompound) {
-        super.a(nbttagcompound);
-    }
-
     protected int getLootId() {
         return Item.ARROW.id;
     }
@@ -131,7 +97,14 @@ public class EntitySkeleton extends EntityMonster {
         // CraftBukkit end
     }
 
-    public MonsterType getMonsterType() {
-        return MonsterType.UNDEAD;
+    protected void b(int i) {
+        if (i > 0) {
+            ItemStack itemstack = new ItemStack(Item.BOW);
+
+            EnchantmentManager.a(this.random, itemstack, 5);
+            this.a(itemstack, 0.0F);
+        } else {
+            this.b(Item.BOW.id, 1);
+        }
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java
index 3f2ea7f552..4ed80557f1 100644
--- a/src/main/java/net/minecraft/server/EntitySlime.java
+++ b/src/main/java/net/minecraft/server/EntitySlime.java
@@ -52,15 +52,15 @@ public class EntitySlime extends EntityLiving implements IMonster {
         this.setSize(nbttagcompound.getInt("Size") + 1);
     }
 
-    protected String v() {
+    protected String A() {
         return "slime";
     }
 
-    protected String F() {
+    protected String J() {
         return "mob.slime";
     }
 
-    public void y_() {
+    public void G_() {
         if (!this.world.isStatic && this.world.difficulty == 0 && this.getSize() > 0) {
             this.dead = true;
         }
@@ -69,7 +69,7 @@ public class EntitySlime extends EntityLiving implements IMonster {
         this.c = this.b;
         boolean flag = this.onGround;
 
-        super.y_();
+        super.G_();
         if (this.onGround && !flag) {
             int i = this.getSize();
 
@@ -79,21 +79,21 @@ public class EntitySlime extends EntityLiving implements IMonster {
                 float f2 = MathHelper.sin(f) * (float) i * 0.5F * f1;
                 float f3 = MathHelper.cos(f) * (float) i * 0.5F * f1;
 
-                this.world.a(this.v(), this.locX + (double) f2, this.boundingBox.b, this.locZ + (double) f3, 0.0D, 0.0D, 0.0D);
+                this.world.a(this.A(), this.locX + (double) f2, this.boundingBox.b, this.locZ + (double) f3, 0.0D, 0.0D, 0.0D);
             }
 
-            if (this.H()) {
-                this.world.makeSound(this, this.F(), this.o(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) / 0.8F);
+            if (this.K()) {
+                this.world.makeSound(this, this.J(), this.p(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) / 0.8F);
             }
 
             this.a = -0.5F;
         }
 
-        this.C();
+        this.F();
     }
 
-    protected void m_() {
-        this.au();
+    protected void d_() {
+        this.aF();
         EntityHuman entityhuman = this.world.findNearbyVulnerablePlayer(this, 16.0D);
 
         if (entityhuman != null) {
@@ -101,14 +101,14 @@ public class EntitySlime extends EntityLiving implements IMonster {
         }
 
         if (this.onGround && this.jumpDelay-- <= 0) {
-            this.jumpDelay = this.B();
+            this.jumpDelay = this.E();
             if (entityhuman != null) {
                 this.jumpDelay /= 3;
             }
 
             this.aZ = true;
-            if (this.J()) {
-                this.world.makeSound(this, this.F(), this.o(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 0.8F);
+            if (this.M()) {
+                this.world.makeSound(this, this.J(), this.p(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 0.8F);
             }
 
             this.a = 1.0F;
@@ -122,15 +122,15 @@ public class EntitySlime extends EntityLiving implements IMonster {
         }
     }
 
-    protected void C() {
+    protected void F() {
         this.a *= 0.6F;
     }
 
-    protected int B() {
+    protected int E() {
         return this.random.nextInt(20) + 10;
     }
 
-    protected EntitySlime z() {
+    protected EntitySlime D() {
         return new EntitySlime(this.world);
     }
 
@@ -155,7 +155,7 @@ public class EntitySlime extends EntityLiving implements IMonster {
             for (int k = 0; k < j; ++k) {
                 float f = ((float) (k % 2) - 0.5F) * (float) i / 4.0F;
                 float f1 = ((float) (k / 2) - 0.5F) * (float) i / 4.0F;
-                EntitySlime entityslime = this.z();
+                EntitySlime entityslime = this.D();
 
                 entityslime.setSize(i / 2);
                 entityslime.setPositionRotation(this.locX + (double) f, this.locY + 0.5D, this.locZ + (double) f1, this.random.nextFloat() * 360.0F, 0.0F);
@@ -167,28 +167,28 @@ public class EntitySlime extends EntityLiving implements IMonster {
     }
 
     public void a_(EntityHuman entityhuman) {
-        if (this.D()) {
+        if (this.G()) {
             int i = this.getSize();
 
-            if (this.g(entityhuman) && (double) this.h(entityhuman) < 0.6D * (double) i && entityhuman.damageEntity(DamageSource.mobAttack(this), this.E())) {
+            if (this.h(entityhuman) && (double) this.i(entityhuman) < 0.6D * (double) i && entityhuman.damageEntity(DamageSource.mobAttack(this), this.H())) {
                 this.world.makeSound(this, "mob.slimeattack", 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
             }
         }
     }
 
-    protected boolean D() {
+    protected boolean G() {
         return this.getSize() > 1;
     }
 
-    protected int E() {
+    protected int H() {
         return this.getSize();
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.slime";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.slime";
     }
 
@@ -202,19 +202,19 @@ public class EntitySlime extends EntityLiving implements IMonster {
         return (this.getSize() == 1 || this.world.difficulty > 0) && this.random.nextInt(10) == 0 && chunk.a(987234911L).nextInt(10) == 0 && this.locY < 40.0D ? super.canSpawn() : false;
     }
 
-    protected float o() {
+    protected float p() {
         return 0.4F * (float) this.getSize();
     }
 
-    public int x() {
+    public int C() {
         return 0;
     }
 
-    protected boolean J() {
+    protected boolean M() {
         return this.getSize() > 1;
     }
 
-    protected boolean H() {
+    protected boolean K() {
         return this.getSize() > 2;
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntitySmallFireball.java b/src/main/java/net/minecraft/server/EntitySmallFireball.java
index 0393304357..6f63270047 100644
--- a/src/main/java/net/minecraft/server/EntitySmallFireball.java
+++ b/src/main/java/net/minecraft/server/EntitySmallFireball.java
@@ -20,6 +20,11 @@ public class EntitySmallFireball extends EntityFireball {
         this.b(0.3125F, 0.3125F);
     }
 
+    public EntitySmallFireball(World world, double d0, double d1, double d2, double d3, double d4, double d5) {
+        super(world, d0, d1, d2, d3, d4, d5);
+        this.b(0.3125F, 0.3125F);
+    }
+
     protected void a(MovingObjectPosition movingobjectposition) {
         if (!this.world.isStatic) {
             // CraftBukkit start - projectile hit event
@@ -84,7 +89,7 @@ public class EntitySmallFireball extends EntityFireball {
         }
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return false;
     }
 
diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java
index 16fc2e4196..59fe5a0c5c 100644
--- a/src/main/java/net/minecraft/server/EntitySnowman.java
+++ b/src/main/java/net/minecraft/server/EntitySnowman.java
@@ -13,36 +13,41 @@ public class EntitySnowman extends EntityGolem {
         super(world);
         this.texture = "/mob/snowman.png";
         this.b(0.4F, 1.8F);
+        this.ak().a(true);
+        this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 0.25F, 2, 20));
+        this.goalSelector.a(2, new PathfinderGoalRandomStroll(this, 0.2F));
+        this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
+        this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this));
+        this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget(this, EntityMonster.class, 16.0F, 0, true));
+    }
+
+    public boolean c_() {
+        return true;
     }
 
     public int getMaxHealth() {
         return 4;
     }
 
-    public void d() {
-        super.d();
-        if (this.target == null && !this.E() && this.world.random.nextInt(100) == 0) {
-            List list = this.world.a(EntityMonster.class, AxisAlignedBB.b(this.locX, this.locY, this.locZ, this.locX + 1.0D, this.locY + 1.0D, this.locZ + 1.0D).grow(16.0D, 4.0D, 16.0D));
-
-            if (!list.isEmpty()) {
-                this.setTarget((Entity) list.get(this.world.random.nextInt(list.size())));
-            }
+    public void e() {
+        super.e();
+        if (this.aS()) {
+            this.damageEntity(DamageSource.DROWN, 1);
         }
 
         int i = MathHelper.floor(this.locX);
-        int j = MathHelper.floor(this.locY);
-        int k = MathHelper.floor(this.locZ);
+        int j = MathHelper.floor(this.locZ);
 
-        if (this.world.getWorldChunkManager().a(i, j, k) > 1.0F) {
+        if (this.world.getBiome(i, j).h() > 1.0F) {
             this.damageEntity(DamageSource.BURN, 1);
         }
 
         for (i = 0; i < 4; ++i) {
             j = MathHelper.floor(this.locX + (double) ((float) (i % 2 * 2 - 1) * 0.25F));
-            k = MathHelper.floor(this.locY);
+            int k = MathHelper.floor(this.locY);
             int l = MathHelper.floor(this.locZ + (double) ((float) (i / 2 % 2 * 2 - 1) * 0.25F));
 
-            if (this.world.getTypeId(j, k, l) == 0 && this.world.getWorldChunkManager().a(j, k, l) < 0.8F && Block.SNOW.canPlace(this.world, j, k, l)) {
+            if (this.world.getTypeId(j, k, l) == 0 && this.world.getBiome(j, l).h() < 0.8F && Block.SNOW.canPlace(this.world, j, k, l)) {
                 // CraftBukkit start
                 BlockState blockState = this.world.getWorld().getBlockAt(j, k, l).getState();
                 blockState.setTypeId(Block.SNOW.id);
@@ -58,27 +63,6 @@ public class EntitySnowman extends EntityGolem {
         }
     }
 
-    protected void a(Entity entity, float f) {
-        if (f < 10.0F) {
-            double d0 = entity.locX - this.locX;
-            double d1 = entity.locZ - this.locZ;
-
-            if (this.attackTicks == 0) {
-                EntitySnowball entitysnowball = new EntitySnowball(this.world, this);
-                double d2 = entity.locY + (double) entity.getHeadHeight() - 1.100000023841858D - entitysnowball.locY;
-                float f1 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 0.2F;
-
-                this.world.makeSound(this, "random.bow", 1.0F, 1.0F / (this.random.nextFloat() * 0.4F + 0.8F));
-                this.world.addEntity(entitysnowball);
-                entitysnowball.a(d0, d2 + (double) f1, d1, 1.6F, 12.0F);
-                this.attackTicks = 10;
-            }
-
-            this.yaw = (float) (Math.atan2(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F;
-            this.e = true;
-        }
-    }
-
     public void b(NBTTagCompound nbttagcompound) {
         super.b(nbttagcompound);
     }
diff --git a/src/main/java/net/minecraft/server/EntitySpider.java b/src/main/java/net/minecraft/server/EntitySpider.java
index b57f75e39b..e1c164ce2c 100644
--- a/src/main/java/net/minecraft/server/EntitySpider.java
+++ b/src/main/java/net/minecraft/server/EntitySpider.java
@@ -22,12 +22,12 @@ public class EntitySpider extends EntityMonster {
         this.datawatcher.a(16, new Byte((byte) 0));
     }
 
-    public void d() {
-        super.d();
+    public void e() {
+        super.e();
     }
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         if (!this.world.isStatic) {
             this.a(this.positionChanged);
         }
@@ -37,7 +37,7 @@ public class EntitySpider extends EntityMonster {
         return 16;
     }
 
-    public double q() {
+    public double x_() {
         return (double) this.length * 0.75D - 0.5D;
     }
 
@@ -46,7 +46,7 @@ public class EntitySpider extends EntityMonster {
     }
 
     protected Entity findTarget() {
-        float f = this.a(1.0F);
+        float f = this.b(1.0F);
 
         if (f < 0.5F) {
             double d0 = 16.0D;
@@ -57,20 +57,20 @@ public class EntitySpider extends EntityMonster {
         }
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.spider";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.spider";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.spiderdeath";
     }
 
     protected void a(Entity entity, float f) {
-        float f1 = this.a(1.0F);
+        float f1 = this.b(1.0F);
 
         if (f1 > 0.5F && this.random.nextInt(100) == 0) {
             // CraftBukkit start
@@ -137,11 +137,11 @@ public class EntitySpider extends EntityMonster {
         // CraftBukkit end
     }
 
-    public boolean r() {
-        return this.u();
+    public boolean t() {
+        return this.w();
     }
 
-    public void s() {}
+    public void u() {}
 
     public MonsterType getMonsterType() {
         return MonsterType.ARTHROPOD;
@@ -151,7 +151,7 @@ public class EntitySpider extends EntityMonster {
         return mobeffect.getEffectId() == MobEffectList.POISON.id ? false : super.a(mobeffect);
     }
 
-    public boolean u() {
+    public boolean w() {
         return (this.datawatcher.getByte(16) & 1) != 0;
     }
 
diff --git a/src/main/java/net/minecraft/server/EntitySquid.java b/src/main/java/net/minecraft/server/EntitySquid.java
index c8204d5a67..fcc747adb6 100644
--- a/src/main/java/net/minecraft/server/EntitySquid.java
+++ b/src/main/java/net/minecraft/server/EntitySquid.java
@@ -38,19 +38,19 @@ public class EntitySquid extends EntityWaterAnimal {
         super.a(nbttagcompound);
     }
 
-    protected String c_() {
+    protected String i() {
         return null;
     }
 
-    protected String m() {
+    protected String j() {
         return null;
     }
 
-    protected String n() {
+    protected String k() {
         return null;
     }
 
-    protected float o() {
+    protected float p() {
         return 0.4F;
     }
 
@@ -75,12 +75,12 @@ public class EntitySquid extends EntityWaterAnimal {
         return super.b(entityhuman);
     }
 
-    public boolean aK() {
+    public boolean aT() {
         return this.world.a(this.boundingBox.grow(0.0D, -0.6000000238418579D, 0.0D), Material.WATER, this);
     }
 
-    public void d() {
-        super.d();
+    public void e() {
+        super.e();
         this.b = this.a;
         this.g = this.c;
         this.i = this.h;
@@ -93,7 +93,7 @@ public class EntitySquid extends EntityWaterAnimal {
             }
         }
 
-        if (this.aK()) {
+        if (this.aT()) {
             float f;
 
             if (this.h < 3.1415927F) {
@@ -139,7 +139,7 @@ public class EntitySquid extends EntityWaterAnimal {
         this.move(this.motX, this.motY, this.motZ);
     }
 
-    protected void m_() {
+    protected void d_() {
         ++this.aV;
         if (this.aV > 100) {
             this.o = this.p = this.q = 0.0F;
@@ -151,10 +151,10 @@ public class EntitySquid extends EntityWaterAnimal {
             this.q = MathHelper.sin(f) * 0.2F;
         }
 
-        this.au();
+        this.aF();
     }
 
     public boolean canSpawn() {
-        return this.locY > 45.0D && this.locY < (double) this.world.seaLevel && super.canSpawn();
+        return this.locY > 45.0D && this.locY < 63.0D && super.canSpawn();
     }
 }
diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java
index d4deb68bd2..66519e0c64 100644
--- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java
+++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java
@@ -26,9 +26,9 @@ public class EntityTNTPrimed extends Entity {
         this.setPosition(d0, d1, d2);
         float f = (float) (Math.random() * 3.1415927410125732D * 2.0D);
 
-        this.motX = (double) (-MathHelper.sin(f * 3.1415927F / 180.0F) * 0.02F);
+        this.motX = (double) (-((float) Math.sin((double) f)) * 0.02F);
         this.motY = 0.20000000298023224D;
-        this.motZ = (double) (-MathHelper.cos(f * 3.1415927F / 180.0F) * 0.02F);
+        this.motZ = (double) (-((float) Math.cos((double) f)) * 0.02F);
         this.fuseTicks = 80;
         this.lastX = d0;
         this.lastY = d1;
@@ -41,11 +41,11 @@ public class EntityTNTPrimed extends Entity {
         return false;
     }
 
-    public boolean e_() {
+    public boolean o_() {
         return !this.dead;
     }
 
-    public void y_() {
+    public void G_() {
         this.lastX = this.locX;
         this.lastY = this.locY;
         this.lastZ = this.locZ;
diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java
index 5a9c907fcc..ac7b95a594 100644
--- a/src/main/java/net/minecraft/server/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/EntityTracker.java
@@ -51,6 +51,8 @@ public class EntityTracker {
             this.addEntity(entity, 64, 10, true);
         } else if (entity instanceof EntityPotion) {
             this.addEntity(entity, 64, 10, true);
+        } else if (entity instanceof EntityThrownExpBottle) {
+            this.addEntity(entity, 64, 10, true);
         } else if (entity instanceof EntityItem) {
             this.addEntity(entity, 64, 20, true);
         } else if (entity instanceof EntityMinecart) {
@@ -128,7 +130,7 @@ public class EntityTracker {
             EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next();
 
             entitytrackerentry.track(this.world.players); // CraftBukkit
-            if (entitytrackerentry.m && entitytrackerentry.tracker instanceof EntityPlayer) {
+            if (entitytrackerentry.n && entitytrackerentry.tracker instanceof EntityPlayer) {
                 arraylist.add((EntityPlayer) entitytrackerentry.tracker);
             }
         }
diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
index e50a70f645..00013fa0dd 100644
--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
@@ -16,17 +16,18 @@ public class EntityTrackerEntry {
     public int zLoc;
     public int yRot;
     public int xRot;
-    public double i;
+    public int i;
     public double j;
     public double k;
-    public int l = 0;
-    private double o;
+    public double l;
+    public int m = 0;
     private double p;
     private double q;
-    private boolean r = false;
+    private double r;
+    private boolean s = false;
     private boolean isMoving;
-    private int t = 0;
-    public boolean m = false;
+    private int u = 0;
+    public boolean n = false;
     public Set trackedPlayers = new HashSet();
 
     public EntityTrackerEntry(Entity entity, int i, int j, boolean flag) {
@@ -39,6 +40,7 @@ public class EntityTrackerEntry {
         this.zLoc = MathHelper.floor(entity.locZ * 32.0D);
         this.yRot = MathHelper.d(entity.yaw * 256.0F / 360.0F);
         this.xRot = MathHelper.d(entity.pitch * 256.0F / 360.0F);
+        this.i = MathHelper.d(entity.aq() * 256.0F / 360.0F);
     }
 
     public boolean equals(Object object) {
@@ -50,18 +52,18 @@ public class EntityTrackerEntry {
     }
 
     public void track(List list) {
-        this.m = false;
-        if (!this.r || this.tracker.e(this.o, this.p, this.q) > 16.0D) {
-            this.o = this.tracker.locX;
-            this.p = this.tracker.locY;
-            this.q = this.tracker.locZ;
-            this.r = true;
-            this.m = true;
+        this.n = false;
+        if (!this.s || this.tracker.e(this.p, this.q, this.r) > 16.0D) {
+            this.p = this.tracker.locX;
+            this.q = this.tracker.locY;
+            this.r = this.tracker.locZ;
+            this.s = true;
+            this.n = true;
             this.scanPlayers(list);
         }
 
-        ++this.t;
-        if (++this.l % this.c == 0 || this.tracker.ce) {
+        ++this.u;
+        if (this.m++ % this.c == 0 || this.tracker.ce) {
             int i = MathHelper.floor(this.tracker.locX * 32.0D);
             int j = MathHelper.floor(this.tracker.locY * 32.0D);
             int k = MathHelper.floor(this.tracker.locZ * 32.0D);
@@ -87,7 +89,7 @@ public class EntityTrackerEntry {
             }
             // CraftBukkit end
 
-            if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.t <= 400) {
+            if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.u <= 400) {
                 if (flag && flag1) {
                     object = new Packet33RelEntityMoveLook(this.tracker.id, (byte) j1, (byte) k1, (byte) l1, (byte) l, (byte) i1);
                 } else if (flag) {
@@ -96,7 +98,7 @@ public class EntityTrackerEntry {
                     object = new Packet32EntityLook(this.tracker.id, (byte) l, (byte) i1);
                 }
             } else {
-                this.t = 0;
+                this.u = 0;
                 this.tracker.locX = (double) i / 32.0D;
                 this.tracker.locY = (double) j / 32.0D;
                 this.tracker.locZ = (double) k / 32.0D;
@@ -109,17 +111,17 @@ public class EntityTrackerEntry {
             }
 
             if (this.isMoving) {
-                double d0 = this.tracker.motX - this.i;
-                double d1 = this.tracker.motY - this.j;
-                double d2 = this.tracker.motZ - this.k;
+                double d0 = this.tracker.motX - this.j;
+                double d1 = this.tracker.motY - this.k;
+                double d2 = this.tracker.motZ - this.l;
                 double d3 = 0.02D;
                 double d4 = d0 * d0 + d1 * d1 + d2 * d2;
 
                 if (d4 > d3 * d3 || d4 > 0.0D && this.tracker.motX == 0.0D && this.tracker.motY == 0.0D && this.tracker.motZ == 0.0D) {
-                    this.i = this.tracker.motX;
-                    this.j = this.tracker.motY;
-                    this.k = this.tracker.motZ;
-                    this.broadcast(new Packet28EntityVelocity(this.tracker.id, this.i, this.j, this.k));
+                    this.j = this.tracker.motX;
+                    this.k = this.tracker.motY;
+                    this.l = this.tracker.motZ;
+                    this.broadcast(new Packet28EntityVelocity(this.tracker.id, this.j, this.k, this.l));
                 }
             }
 
@@ -132,6 +134,14 @@ public class EntityTrackerEntry {
             if (datawatcher.a()) {
                 this.broadcastIncludingSelf(new Packet40EntityMetadata(this.tracker.id, datawatcher));
             }
+
+            int i2 = MathHelper.d(this.tracker.aq() * 256.0F / 360.0F);
+
+            if (Math.abs(i2 - this.i) >= 4) {
+                this.broadcast(new Packet35EntityHeadRotation(this.tracker.id, (byte) i2));
+                this.i = i2;
+            }
+
             /* CraftBukkit start - code moved up
             if (flag) {
                 this.xLoc = i;
@@ -310,6 +320,8 @@ public class EntityTrackerEntry {
                 return new Packet23VehicleSpawn(this.tracker, 61);
             } else if (this.tracker instanceof EntityPotion) {
                 return new Packet23VehicleSpawn(this.tracker, 73, ((EntityPotion) this.tracker).getPotionValue());
+            } else if (this.tracker instanceof EntityThrownExpBottle) {
+                return new Packet23VehicleSpawn(this.tracker, 75);
             } else if (this.tracker instanceof EntityEnderPearl) {
                 return new Packet23VehicleSpawn(this.tracker, 65);
             } else if (this.tracker instanceof EntityEnderSignal) {
diff --git a/src/main/java/net/minecraft/server/EntityWeatherLighting.java b/src/main/java/net/minecraft/server/EntityWeatherLighting.java
index 6a715f2586..a6eb9b4fa6 100644
--- a/src/main/java/net/minecraft/server/EntityWeatherLighting.java
+++ b/src/main/java/net/minecraft/server/EntityWeatherLighting.java
@@ -73,8 +73,8 @@ public class EntityWeatherLighting extends EntityWeather {
         }
     }
 
-    public void y_() {
-        super.y_();
+    public void G_() {
+        super.G_();
         if (this.lifeTicks == 2) {
             this.world.makeSound(this.locX, this.locY, this.locZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.random.nextFloat() * 0.2F);
             this.world.makeSound(this.locX, this.locY, this.locZ, "random.explode", 2.0F, 0.5F + this.random.nextFloat() * 0.2F);
@@ -118,7 +118,7 @@ public class EntityWeatherLighting extends EntityWeather {
                 entity.a(this);
             }
 
-            this.world.s = 2;
+            this.world.n = 2;
         }
     }
 
diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java
deleted file mode 100644
index be4607b49c..0000000000
--- a/src/main/java/net/minecraft/server/EntityWolf.java
+++ /dev/null
@@ -1,487 +0,0 @@
-package net.minecraft.server;
-
-import java.util.Iterator;
-import java.util.List;
-
-// CraftBukkit start
-import org.bukkit.Bukkit;
-import org.bukkit.craftbukkit.entity.CraftEntity;
-import org.bukkit.craftbukkit.event.CraftEventFactory;
-import org.bukkit.event.entity.EntityDamageByEntityEvent;
-import org.bukkit.event.entity.EntityDamageEvent;
-import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
-import org.bukkit.event.entity.EntityTargetEvent;
-// CraftBukkit end
-
-public class EntityWolf extends EntityAnimal {
-
-    private boolean a = false;
-    private float b;
-    private float c;
-    private boolean g;
-    private boolean h;
-    private float i;
-    private float j;
-
-    public EntityWolf(World world) {
-        super(world);
-        this.texture = "/mob/wolf.png";
-        this.b(0.8F, 0.8F);
-        this.bb = 1.1F;
-    }
-
-    public int getMaxHealth() {
-        return this.isTamed() ? 20 : 8;
-    }
-
-    protected void b() {
-        super.b();
-        this.datawatcher.a(16, Byte.valueOf((byte) 0));
-        this.datawatcher.a(17, "");
-        this.datawatcher.a(18, new Integer(this.getHealth()));
-    }
-
-    protected boolean g_() {
-        return false;
-    }
-
-    public void b(NBTTagCompound nbttagcompound) {
-        super.b(nbttagcompound);
-        nbttagcompound.setBoolean("Angry", this.isAngry());
-        nbttagcompound.setBoolean("Sitting", this.isSitting());
-        if (this.getOwnerName() == null) {
-            nbttagcompound.setString("Owner", "");
-        } else {
-            nbttagcompound.setString("Owner", this.getOwnerName());
-        }
-    }
-
-    public void a(NBTTagCompound nbttagcompound) {
-        super.a(nbttagcompound);
-        this.setAngry(nbttagcompound.getBoolean("Angry"));
-        this.setSitting(nbttagcompound.getBoolean("Sitting"));
-        String s = nbttagcompound.getString("Owner");
-
-        if (s.length() > 0) {
-            this.setOwnerName(s);
-            this.setTamed(true);
-        }
-    }
-
-    protected boolean d_() {
-        return this.isAngry();
-    }
-
-    protected String c_() {
-        return this.isAngry() ? "mob.wolf.growl" : (this.random.nextInt(3) == 0 ? (this.isTamed() && this.datawatcher.getInt(18) < 10 ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark");
-    }
-
-    protected String m() {
-        return "mob.wolf.hurt";
-    }
-
-    protected String n() {
-        return "mob.wolf.death";
-    }
-
-    protected float o() {
-        return 0.4F;
-    }
-
-    protected int getLootId() {
-        return -1;
-    }
-
-    protected void m_() {
-        super.m_();
-        if (!this.e && !this.E() && this.isTamed() && this.vehicle == null) {
-            EntityHuman entityhuman = this.world.a(this.getOwnerName());
-
-            if (entityhuman != null) {
-                float f = entityhuman.h(this);
-
-                if (f > 5.0F) {
-                    this.c(entityhuman, f);
-                }
-            } else if (!this.aK()) {
-                this.setSitting(true);
-            }
-        } else if (this.target == null && !this.E() && !this.isTamed() && this.world.random.nextInt(100) == 0) {
-            List list = this.world.a(EntitySheep.class, AxisAlignedBB.b(this.locX, this.locY, this.locZ, this.locX + 1.0D, this.locY + 1.0D, this.locZ + 1.0D).grow(16.0D, 4.0D, 16.0D));
-
-            if (!list.isEmpty()) {
-                // CraftBukkit start
-                Entity entity = (Entity) list.get(this.world.random.nextInt(list.size()));
-                org.bukkit.entity.Entity bukkitTarget = entity == null ? null : entity.getBukkitEntity();
-
-                EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), bukkitTarget, EntityTargetEvent.TargetReason.RANDOM_TARGET);
-                this.world.getServer().getPluginManager().callEvent(event);
-
-                if (!event.isCancelled() || event.getTarget() != null) {
-                    this.setTarget(entity);
-                }
-                // CraftBukkit end
-            }
-        }
-
-        if (this.aK()) {
-            this.setSitting(false);
-        }
-
-        if (!this.world.isStatic) {
-            this.datawatcher.watch(18, Integer.valueOf(this.getHealth()));
-        }
-    }
-
-    public void d() {
-        super.d();
-        this.a = false;
-        if (this.aw() && !this.E() && !this.isAngry()) {
-            Entity entity = this.ax();
-
-            if (entity instanceof EntityHuman) {
-                EntityHuman entityhuman = (EntityHuman) entity;
-                ItemStack itemstack = entityhuman.inventory.getItemInHand();
-
-                if (itemstack != null) {
-                    if (!this.isTamed() && itemstack.id == Item.BONE.id) {
-                        this.a = true;
-                    } else if (this.isTamed() && Item.byId[itemstack.id] instanceof ItemFood) {
-                        this.a = ((ItemFood) Item.byId[itemstack.id]).q();
-                    }
-                }
-            }
-        }
-
-        if (!this.world.isStatic && this.g && !this.h && !this.E() && this.onGround) {
-            this.h = true;
-            this.i = 0.0F;
-            this.j = 0.0F;
-            this.world.broadcastEntityEffect(this, (byte) 8);
-        }
-    }
-
-    public void y_() {
-        super.y_();
-        this.c = this.b;
-        if (this.a) {
-            this.b += (1.0F - this.b) * 0.4F;
-        } else {
-            this.b += (0.0F - this.b) * 0.4F;
-        }
-
-        if (this.a) {
-            this.bc = 10;
-        }
-
-        if (this.aJ()) {
-            this.g = true;
-            this.h = false;
-            this.i = 0.0F;
-            this.j = 0.0F;
-        } else if ((this.g || this.h) && this.h) {
-            if (this.i == 0.0F) {
-                this.world.makeSound(this, "mob.wolf.shake", this.o(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
-            }
-
-            this.j = this.i;
-            this.i += 0.05F;
-            if (this.j >= 2.0F) {
-                this.g = false;
-                this.h = false;
-                this.j = 0.0F;
-                this.i = 0.0F;
-            }
-
-            if (this.i > 0.4F) {
-                float f = (float) this.boundingBox.b;
-                int i = (int) (MathHelper.sin((this.i - 0.4F) * 3.1415927F) * 7.0F);
-
-                for (int j = 0; j < i; ++j) {
-                    float f1 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
-                    float f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
-
-                    this.world.a("splash", this.locX + (double) f1, (double) (f + 0.8F), this.locZ + (double) f2, this.motX, this.motY, this.motZ);
-                }
-            }
-        }
-    }
-
-    public float getHeadHeight() {
-        return this.length * 0.8F;
-    }
-
-    public int x() {
-        return this.isSitting() ? 20 : super.x();
-    }
-
-    private void c(Entity entity, float f) {
-        PathEntity pathentity = this.world.findPath(this, entity, 16.0F);
-
-        if (pathentity == null && f > 12.0F) {
-            int i = MathHelper.floor(entity.locX) - 2;
-            int j = MathHelper.floor(entity.locZ) - 2;
-            int k = MathHelper.floor(entity.boundingBox.b);
-
-            for (int l = 0; l <= 4; ++l) {
-                for (int i1 = 0; i1 <= 4; ++i1) {
-                    if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && this.world.e(i + l, k - 1, j + i1) && !this.world.e(i + l, k, j + i1) && !this.world.e(i + l, k + 1, j + i1)) {
-                        this.setPositionRotation((double) ((float) (i + l) + 0.5F), (double) k, (double) ((float) (j + i1) + 0.5F), this.yaw, this.pitch);
-                        return;
-                    }
-                }
-            }
-        } else {
-            this.setPathEntity(pathentity);
-        }
-    }
-
-    protected boolean v() {
-        return this.isSitting() || this.h;
-    }
-
-    public boolean damageEntity(DamageSource damagesource, int i) {
-        Entity entity = damagesource.getEntity();
-
-        this.setSitting(false);
-        if (entity != null && !(entity instanceof EntityHuman) && !(entity instanceof EntityArrow)) {
-            i = (i + 1) / 2;
-        }
-
-        if (!super.damageEntity(damagesource, i)) {
-            return false;
-        } else {
-            if (!this.isTamed() && !this.isAngry()) {
-                if (entity instanceof EntityHuman) {
-                    // CraftBukkit start
-                    org.bukkit.entity.Entity bukkitTarget = entity == null ? null : entity.getBukkitEntity();
-
-                    EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), bukkitTarget, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY);
-                    this.world.getServer().getPluginManager().callEvent(event);
-
-                    if (!event.isCancelled()) {
-                        if (event.getTarget() == null) {
-                            this.target = null;
-                        } else {
-                            this.setAngry(true);
-                            this.target = ((CraftEntity) event.getTarget()).getHandle();
-                        }
-                    }
-                    // CraftBukkit end
-                }
-
-                if (entity instanceof EntityArrow && ((EntityArrow) entity).shooter != null) {
-                    entity = ((EntityArrow) entity).shooter;
-                }
-
-                if (entity instanceof EntityLiving) {
-                    List list = this.world.a(EntityWolf.class, AxisAlignedBB.b(this.locX, this.locY, this.locZ, this.locX + 1.0D, this.locY + 1.0D, this.locZ + 1.0D).grow(16.0D, 4.0D, 16.0D));
-                    Iterator iterator = list.iterator();
-
-                    while (iterator.hasNext()) {
-                        Entity entity1 = (Entity) iterator.next();
-                        EntityWolf entitywolf = (EntityWolf) entity1;
-
-                        if (!entitywolf.isTamed() && entitywolf.target == null) {
-                            // CraftBukkit start
-                            org.bukkit.entity.Entity bukkitTarget = entity == null ? null : entity.getBukkitEntity();
-
-                            EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), bukkitTarget, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY);
-                            this.world.getServer().getPluginManager().callEvent(event);
-
-                            if (!event.isCancelled()) {
-                                if (event.getTarget() == null) {
-                                    this.target = null;
-                                } else {
-                                    entitywolf.target = (Entity) entity;
-                                    if (entity instanceof EntityHuman) {
-                                        entitywolf.setAngry(true);
-                                    }
-                                }
-                            }
-                            // CraftBukkit end
-                        }
-                    }
-                }
-            } else if (entity != this && entity != null) {
-                if (this.isTamed() && entity instanceof EntityHuman && ((EntityHuman) entity).name.equalsIgnoreCase(this.getOwnerName())) {
-                    return true;
-                }
-
-                this.target = entity;
-            }
-
-            return true;
-        }
-    }
-
-    protected Entity findTarget() {
-        return this.isAngry() ? this.world.findNearbyPlayer(this, 16.0D) : null;
-    }
-
-    protected void a(Entity entity, float f) {
-        if (f > 2.0F && f < 6.0F && this.random.nextInt(10) == 0) {
-            if (this.onGround) {
-                double d0 = entity.locX - this.locX;
-                double d1 = entity.locZ - this.locZ;
-                float f1 = MathHelper.sqrt(d0 * d0 + d1 * d1);
-
-                this.motX = d0 / (double) f1 * 0.5D * 0.800000011920929D + this.motX * 0.20000000298023224D;
-                this.motZ = d1 / (double) f1 * 0.5D * 0.800000011920929D + this.motZ * 0.20000000298023224D;
-                this.motY = 0.4000000059604645D;
-            }
-        } else if ((double) f < 1.5D && entity.boundingBox.e > this.boundingBox.b && entity.boundingBox.b < this.boundingBox.e) {
-            this.attackTicks = 20;
-            byte b0 = 2;
-
-            if (this.isTamed()) {
-                b0 = 4;
-            }
-            // CraftBukkit start
-            org.bukkit.entity.Entity damager = this.getBukkitEntity();
-            org.bukkit.entity.Entity damagee = entity == null ? null : entity.getBukkitEntity();
-
-            EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK, b0);
-            Bukkit.getPluginManager().callEvent(event);
-
-            if (event.isCancelled()) {
-                return;
-            }
-
-            entity.damageEntity(DamageSource.mobAttack(this), event.getDamage());
-            // CraftBukkit end
-        }
-    }
-
-    public boolean b(EntityHuman entityhuman) {
-        ItemStack itemstack = entityhuman.inventory.getItemInHand();
-
-        if (!this.isTamed()) {
-            if (itemstack != null && itemstack.id == Item.BONE.id && !this.isAngry()) {
-                --itemstack.count;
-                if (itemstack.count <= 0) {
-                    entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
-                }
-
-                if (!this.world.isStatic) {
-                    // CraftBukkit start - added event call and isCancelled check.
-                    if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
-                        // CraftBukkit end
-                        this.setTamed(true);
-                        this.setPathEntity((PathEntity) null);
-                        this.setSitting(true);
-                        this.setHealth(20);
-                        this.setOwnerName(entityhuman.name);
-                        this.a(true);
-                        this.world.broadcastEntityEffect(this, (byte) 7);
-                    } else {
-                        this.a(false);
-                        this.world.broadcastEntityEffect(this, (byte) 6);
-                    }
-                }
-
-                return true;
-            }
-        } else {
-            if (itemstack != null && Item.byId[itemstack.id] instanceof ItemFood) {
-                ItemFood itemfood = (ItemFood) Item.byId[itemstack.id];
-
-                if (itemfood.q() && this.datawatcher.getInt(18) < 20) {
-                    --itemstack.count;
-                    this.heal(itemfood.getNutrition(), RegainReason.EATING); // CraftBukkit
-                    if (itemstack.count <= 0) {
-                        entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null);
-                    }
-
-                    return true;
-                }
-            }
-
-            if (entityhuman.name.equalsIgnoreCase(this.getOwnerName())) {
-                if (!this.world.isStatic) {
-                    this.setSitting(!this.isSitting());
-                    this.aZ = false;
-                    this.setPathEntity((PathEntity) null);
-                }
-
-                return true;
-            }
-        }
-
-        return super.b(entityhuman);
-    }
-
-    void a(boolean flag) {
-        String s = "heart";
-
-        if (!flag) {
-            s = "smoke";
-        }
-
-        for (int i = 0; i < 7; ++i) {
-            double d0 = this.random.nextGaussian() * 0.02D;
-            double d1 = this.random.nextGaussian() * 0.02D;
-            double d2 = this.random.nextGaussian() * 0.02D;
-
-            this.world.a(s, this.locX + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, this.locY + 0.5D + (double) (this.random.nextFloat() * this.length), this.locZ + (double) (this.random.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2);
-        }
-    }
-
-    public int p() {
-        return 8;
-    }
-
-    public String getOwnerName() {
-        return this.datawatcher.getString(17);
-    }
-
-    public void setOwnerName(String s) {
-        this.datawatcher.watch(17, s);
-    }
-
-    public boolean isSitting() {
-        return (this.datawatcher.getByte(16) & 1) != 0;
-    }
-
-    public void setSitting(boolean flag) {
-        byte b0 = this.datawatcher.getByte(16);
-
-        if (flag) {
-            this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1)));
-        } else {
-            this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2)));
-        }
-    }
-
-    public boolean isAngry() {
-        return (this.datawatcher.getByte(16) & 2) != 0;
-    }
-
-    public void setAngry(boolean flag) {
-        byte b0 = this.datawatcher.getByte(16);
-
-        if (flag) {
-            this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 2)));
-        } else {
-            this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -3)));
-        }
-    }
-
-    public boolean isTamed() {
-        return (this.datawatcher.getByte(16) & 4) != 0;
-    }
-
-    public void setTamed(boolean flag) {
-        byte b0 = this.datawatcher.getByte(16);
-
-        if (flag) {
-            this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 4)));
-        } else {
-            this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -5)));
-        }
-    }
-
-    protected EntityAnimal createChild(EntityAnimal entityanimal) {
-        return new EntityWolf(this.world);
-    }
-}
diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java
index 472cea6480..6c053498aa 100644
--- a/src/main/java/net/minecraft/server/EntityZombie.java
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
@@ -7,30 +7,38 @@ public class EntityZombie extends EntityMonster {
     public EntityZombie(World world) {
         super(world);
         this.texture = "/mob/zombie.png";
-        this.bb = 0.5F;
+        this.bb = 0.23F;
         this.damage = 4;
-        this.goalSelector.a(1, new PathfinderGoalFloat(this));
-        this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, world, 16.0F));
-        this.goalSelector.a(3, new PathfinderGoalRandomStroll(this));
-        this.goalSelector.a(4, new PathfinderGoalLookAtPlayer(this, world, 8.0F));
-        this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this));
+        this.ak().b(true);
+        this.goalSelector.a(0, new PathfinderGoalFloat(this));
+        this.goalSelector.a(1, new PathfinderGoalBreakDoor(this));
+        this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, this.bb, false));
+        this.goalSelector.a(3, new PathfinderGoalMeleeAttack(this, EntityVillager.class, this.bb, true));
+        this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, this.bb));
+        this.goalSelector.a(5, new PathfinderGoalMoveThroughVillage(this, this.bb, false));
+        this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, this.bb));
+        this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
+        this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
+        this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false));
+        this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 16.0F, 0, true));
+        this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 16.0F, 0, false));
     }
 
     public int getMaxHealth() {
         return 20;
     }
 
-    public int P() {
+    public int S() {
         return 2;
     }
 
-    protected boolean as() {
-        return false;
+    protected boolean c_() {
+        return true;
     }
 
-    public void d() {
+    public void e() {
         if (this.world.e() && !this.world.isStatic) {
-            float f = this.a(1.0F);
+            float f = this.b(1.0F);
 
             if (f > 0.5F && this.world.isChunkLoaded(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
                 // CraftBukkit start
@@ -44,18 +52,18 @@ public class EntityZombie extends EntityMonster {
             }
         }
 
-        super.d();
+        super.e();
     }
 
-    protected String c_() {
+    protected String i() {
         return "mob.zombie";
     }
 
-    protected String m() {
+    protected String j() {
         return "mob.zombiehurt";
     }
 
-    protected String n() {
+    protected String k() {
         return "mob.zombiedeath";
     }
 
@@ -66,4 +74,23 @@ public class EntityZombie extends EntityMonster {
     public MonsterType getMonsterType() {
         return MonsterType.UNDEAD;
     }
+
+    protected void b(int i) {
+        switch (this.random.nextInt(4)) {
+        case 0:
+            this.b(Item.IRON_SWORD.id, 1);
+            break;
+
+        case 1:
+            this.b(Item.IRON_HELMET.id, 1);
+            break;
+
+        case 2:
+            this.b(Item.IRON_INGOT.id, 1);
+            break;
+
+        case 3:
+            this.b(Item.IRON_SPADE.id, 1);
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index 2b98a69020..469bfe5a4c 100644
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -78,7 +78,7 @@ public class Explosion {
                                 f1 -= (Block.byId[k1].a(this.source) + 0.3F) * f2;
                             }
 
-                            if (f1 > 0.0F && i1 < world.height && i1 >= 0) { // CraftBukkit - Don't wrap explosions
+                            if (f1 > 0.0F && i1 < 256 && i1 >= 0) { // CraftBukkit - Don't wrap explosions
                                 this.blocks.add(new ChunkPosition(l, i1, j1));
                             }
 
@@ -256,7 +256,7 @@ public class Explosion {
                 i1 = this.world.getTypeId(j, k, l);
                 int j1 = this.world.getTypeId(j, k - 1, l);
 
-                if (i1 == 0 && Block.o[j1] && this.h.nextInt(3) == 0) {
+                if (i1 == 0 && Block.n[j1] && this.h.nextInt(3) == 0) {
                     this.world.setTypeId(j, k, l, Block.FIRE.id);
                 }
             }
diff --git a/src/main/java/net/minecraft/server/FoodMetaData.java b/src/main/java/net/minecraft/server/FoodMetaData.java
index 66bb10b390..a659813a94 100644
--- a/src/main/java/net/minecraft/server/FoodMetaData.java
+++ b/src/main/java/net/minecraft/server/FoodMetaData.java
@@ -42,7 +42,7 @@ public class FoodMetaData {
             }
         }
 
-        if (this.foodLevel >= 18 && entityhuman.ab()) {
+        if (this.foodLevel >= 18 && entityhuman.af()) {
             ++this.foodTickTimer;
             if (this.foodTickTimer >= 80) {
                 // CraftBukkit - added RegainReason.
diff --git a/src/main/java/net/minecraft/server/IInventory.java b/src/main/java/net/minecraft/server/IInventory.java
index 63c3f85659..97a8b88de5 100644
--- a/src/main/java/net/minecraft/server/IInventory.java
+++ b/src/main/java/net/minecraft/server/IInventory.java
@@ -16,6 +16,8 @@ public interface IInventory {
 
     ItemStack splitStack(int i, int j);
 
+    ItemStack splitWithoutUpdate(int i);
+
     void setItem(int i, ItemStack itemstack);
 
     String getName();
diff --git a/src/main/java/net/minecraft/server/InventoryCraftResult.java b/src/main/java/net/minecraft/server/InventoryCraftResult.java
index 537f22ae70..98858d5fae 100644
--- a/src/main/java/net/minecraft/server/InventoryCraftResult.java
+++ b/src/main/java/net/minecraft/server/InventoryCraftResult.java
@@ -54,6 +54,17 @@ public class InventoryCraftResult implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         this.items[i] = itemstack;
     }
diff --git a/src/main/java/net/minecraft/server/InventoryCrafting.java b/src/main/java/net/minecraft/server/InventoryCrafting.java
index 1e22c7cccd..ade98090f0 100644
--- a/src/main/java/net/minecraft/server/InventoryCrafting.java
+++ b/src/main/java/net/minecraft/server/InventoryCrafting.java
@@ -73,7 +73,18 @@ public class InventoryCrafting implements IInventory {
     }
 
     public String getName() {
-        return "Crafting";
+        return "container.crafting";
+    }
+
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
     }
 
     public ItemStack splitStack(int i, int j) {
diff --git a/src/main/java/net/minecraft/server/InventoryLargeChest.java b/src/main/java/net/minecraft/server/InventoryLargeChest.java
index 1330a78509..f59550f889 100644
--- a/src/main/java/net/minecraft/server/InventoryLargeChest.java
+++ b/src/main/java/net/minecraft/server/InventoryLargeChest.java
@@ -77,6 +77,10 @@ public class InventoryLargeChest implements IInventory {
         return i >= this.left.getSize() ? this.right.splitStack(i - this.left.getSize(), j) : this.left.splitStack(i, j);
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        return i >= this.left.getSize() ? this.right.splitWithoutUpdate(i - this.left.getSize()) : this.left.splitWithoutUpdate(i);
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         if (i >= this.left.getSize()) {
             this.right.setItem(i - this.left.getSize(), itemstack);
diff --git a/src/main/java/net/minecraft/server/ItemBlock.java b/src/main/java/net/minecraft/server/ItemBlock.java
index 4c0c7f95be..9c8485c844 100644
--- a/src/main/java/net/minecraft/server/ItemBlock.java
+++ b/src/main/java/net/minecraft/server/ItemBlock.java
@@ -25,8 +25,8 @@ public class ItemBlock extends Item {
         int i1 = world.getTypeId(i, j, k);
 
         if (i1 == Block.SNOW.id) {
-            l = 0;
-        } else if (i1 != Block.VINE.id) {
+            l = 1;
+        } else if (i1 != Block.VINE.id && i1 != Block.LONG_GRASS.id && i1 != Block.DEAD_BUSH.id) {
             if (l == 0) {
                 --j;
             }
@@ -56,7 +56,7 @@ public class ItemBlock extends Item {
             return false;
         } else if (!entityhuman.d(i, j, k)) {
             return false;
-        } else if (j == world.height - 1 && Block.byId[this.id].material.isBuildable()) {
+        } else if (j == 255 && Block.byId[this.id].material.isBuildable()) {
             return false;
         }
         // CraftBukkit start
@@ -82,8 +82,8 @@ public class ItemBlock extends Item {
                 if (Block.byId[id] != null) {
                     Block.byId[id].postPlace(world, i, j, k, l);
                     Block.byId[id].postPlace(world, i, j, k, entityhuman);
+                    // CraftBukkit end
                 }
-                // CraftBukkit end
 
                 world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), block.stepSound.getName(), (block.stepSound.getVolume1() + 1.0F) / 2.0F, block.stepSound.getVolume2() * 0.8F);
                 --itemstack.count;
@@ -96,10 +96,10 @@ public class ItemBlock extends Item {
     }
 
     public String a(ItemStack itemstack) {
-        return Block.byId[this.id].n();
+        return Block.byId[this.id].p();
     }
 
     public String getName() {
-        return Block.byId[this.id].n();
+        return Block.byId[this.id].p();
     }
 }
diff --git a/src/main/java/net/minecraft/server/ItemBoat.java b/src/main/java/net/minecraft/server/ItemBoat.java
index a6bb0b2d2f..77767ce418 100644
--- a/src/main/java/net/minecraft/server/ItemBoat.java
+++ b/src/main/java/net/minecraft/server/ItemBoat.java
@@ -36,7 +36,7 @@ public class ItemBoat extends Item {
         if (movingobjectposition == null) {
             return itemstack;
         } else {
-            Vec3D vec3d2 = entityhuman.e(f);
+            Vec3D vec3d2 = entityhuman.f(f);
             boolean flag = false;
             float f9 = 1.0F;
             List list = world.getEntities(entityhuman, entityhuman.boundingBox.a(vec3d2.a * d3, vec3d2.b * d3, vec3d2.c * d3).grow((double) f9, (double) f9, (double) f9));
@@ -44,7 +44,7 @@ public class ItemBoat extends Item {
             for (int i = 0; i < list.size(); ++i) {
                 Entity entity = (Entity) list.get(i);
 
-                if (entity.e_()) {
+                if (entity.o_()) {
                     float f10 = entity.j_();
                     AxisAlignedBB axisalignedbb = entity.boundingBox.grow((double) f10, (double) f10, (double) f10);
 
diff --git a/src/main/java/net/minecraft/server/ItemBow.java b/src/main/java/net/minecraft/server/ItemBow.java
index 05c013e628..0b3fe3a4e7 100644
--- a/src/main/java/net/minecraft/server/ItemBow.java
+++ b/src/main/java/net/minecraft/server/ItemBow.java
@@ -16,7 +16,7 @@ public class ItemBow extends Item {
     public void a(ItemStack itemstack, World world, EntityHuman entityhuman, int i) {
         boolean flag = entityhuman.abilities.canInstantlyBuild || EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_INFINITE.id, itemstack) > 0;
 
-        if (flag || entityhuman.inventory.c(Item.ARROW.id)) {
+        if (flag || entityhuman.inventory.d(Item.ARROW.id)) {
             int j = this.c(itemstack) - i;
             float f = (float) j / 20.0F;
 
@@ -38,7 +38,7 @@ public class ItemBow extends Item {
             int k = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_DAMAGE.id, itemstack);
 
             if (k > 0) {
-                entityarrow.a(entityarrow.j() + (double) k * 0.5D + 0.5D);
+                entityarrow.a(entityarrow.k() + (double) k * 0.5D + 0.5D);
             }
 
             int l = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_KNOCKBACK.id, itemstack);
@@ -66,7 +66,7 @@ public class ItemBow extends Item {
             itemstack.damage(1, entityhuman);
             world.makeSound(entityhuman, "random.bow", 1.0F, 1.0F / (c.nextFloat() * 0.4F + 1.2F) + f * 0.5F);
             if (!flag) {
-                entityhuman.inventory.b(Item.ARROW.id);
+                entityhuman.inventory.c(Item.ARROW.id);
             } else {
                 entityarrow.fromPlayer = false;
             }
@@ -86,7 +86,7 @@ public class ItemBow extends Item {
     }
 
     public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) {
-        if (entityhuman.abilities.canInstantlyBuild || entityhuman.inventory.c(Item.ARROW.id)) {
+        if (entityhuman.abilities.canInstantlyBuild || entityhuman.inventory.d(Item.ARROW.id)) {
             entityhuman.a(itemstack, this.c(itemstack));
         }
 
diff --git a/src/main/java/net/minecraft/server/ItemBucket.java b/src/main/java/net/minecraft/server/ItemBucket.java
index e40460043b..47c7dcc345 100644
--- a/src/main/java/net/minecraft/server/ItemBucket.java
+++ b/src/main/java/net/minecraft/server/ItemBucket.java
@@ -51,7 +51,6 @@ public class ItemBucket extends Item {
                             return itemstack;
                         }
                         world.setTypeId(i, j, k, 0);
-
                         if (entityhuman.abilities.canInstantlyBuild) {
                             return itemstack;
                         }
@@ -68,7 +67,6 @@ public class ItemBucket extends Item {
                             return itemstack;
                         }
                         world.setTypeId(i, j, k, 0);
-
                         if (entityhuman.abilities.canInstantlyBuild) {
                             return itemstack;
                         }
diff --git a/src/main/java/net/minecraft/server/ItemDoor.java b/src/main/java/net/minecraft/server/ItemDoor.java
index 4cecd6db2c..5236292301 100644
--- a/src/main/java/net/minecraft/server/ItemDoor.java
+++ b/src/main/java/net/minecraft/server/ItemDoor.java
@@ -88,11 +88,6 @@ public class ItemDoor extends Item {
             flag2 = true;
         }
 
-        if (flag2) {
-            l = l - 1 & 3;
-            l += 4;
-        }
-
         CraftBlockState blockState = CraftBlockState.getBlockState(world, i, j, k); // CraftBukkit
         world.suppressPhysics = true;
         world.setTypeIdAndData(i, j, k, block.id, l);
@@ -106,7 +101,7 @@ public class ItemDoor extends Item {
             }
         }
         // CraftBukkit end
-        world.setTypeIdAndData(i, j + 1, k, block.id, l + 8);
+        world.setTypeIdAndData(i, j + 1, k, block.id, 8 | (flag2 ? 1 : 0));
         world.suppressPhysics = false;
         world.applyPhysics(i, j, k, block.id);
         world.applyPhysics(i, j + 1, k, block.id);
diff --git a/src/main/java/net/minecraft/server/ItemFishingRod.java b/src/main/java/net/minecraft/server/ItemFishingRod.java
index bad8fd5d2f..1935fe9a15 100644
--- a/src/main/java/net/minecraft/server/ItemFishingRod.java
+++ b/src/main/java/net/minecraft/server/ItemFishingRod.java
@@ -12,10 +12,10 @@ public class ItemFishingRod extends Item {
 
     public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) {
         if (entityhuman.hookedFish != null) {
-            int i = entityhuman.hookedFish.j();
+            int i = entityhuman.hookedFish.k();
 
             itemstack.damage(i, entityhuman);
-            entityhuman.s_();
+            entityhuman.D();
         } else {
             // CraftBukkit start
             PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), null, PlayerFishEvent.State.FISHING);
@@ -31,7 +31,7 @@ public class ItemFishingRod extends Item {
                 world.addEntity(new EntityFishingHook(world, entityhuman));
             }
 
-            entityhuman.s_();
+            entityhuman.D();
         }
 
         return itemstack;
diff --git a/src/main/java/net/minecraft/server/ItemFood.java b/src/main/java/net/minecraft/server/ItemFood.java
index 43990a9aad..ce6979eefe 100644
--- a/src/main/java/net/minecraft/server/ItemFood.java
+++ b/src/main/java/net/minecraft/server/ItemFood.java
@@ -4,20 +4,20 @@ public class ItemFood extends Item {
 
     public final int a;
     private final int b;
-    private final float bS;
-    private final boolean bT;
-    private boolean bU;
-    private int bV;
-    private int bW;
+    private final float bU;
+    private final boolean bV;
+    private boolean bW;
     private int bX;
-    private float bY;
+    private int bY;
+    private int bZ;
+    private float ca;
 
     public ItemFood(int i, int j, float f, boolean flag) {
         super(i);
         this.a = 32;
         this.b = j;
-        this.bT = flag;
-        this.bS = f;
+        this.bV = flag;
+        this.bU = f;
     }
 
     public ItemFood(int i, int j, boolean flag) {
@@ -36,8 +36,8 @@ public class ItemFood extends Item {
         }
         // CraftBukkit end
 
-        if (!world.isStatic && this.bV > 0 && world.random.nextFloat() < this.bY) {
-            entityhuman.addEffect(new MobEffect(this.bV, this.bW * 20, this.bX));
+        if (!world.isStatic && this.bX > 0 && world.random.nextFloat() < this.ca) {
+            entityhuman.addEffect(new MobEffect(this.bX, this.bY * 20, this.bZ));
         }
 
         return itemstack;
@@ -52,7 +52,7 @@ public class ItemFood extends Item {
     }
 
     public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) {
-        if (entityhuman.b(this.bU)) {
+        if (entityhuman.b(this.bW)) {
             entityhuman.a(itemstack, this.c(itemstack));
         }
 
@@ -64,23 +64,23 @@ public class ItemFood extends Item {
     }
 
     public float getSaturationModifier() {
-        return this.bS;
+        return this.bU;
     }
 
     public boolean q() {
-        return this.bT;
+        return this.bV;
     }
 
     public ItemFood a(int i, int j, int k, float f) {
-        this.bV = i;
-        this.bW = j;
-        this.bX = k;
-        this.bY = f;
+        this.bX = i;
+        this.bY = j;
+        this.bZ = k;
+        this.ca = f;
         return this;
     }
 
     public ItemFood r() {
-        this.bU = true;
+        this.bW = true;
         return this;
     }
 
diff --git a/src/main/java/net/minecraft/server/ItemInWorldManager.java b/src/main/java/net/minecraft/server/ItemInWorldManager.java
index 3c75c2c286..743411fa8b 100644
--- a/src/main/java/net/minecraft/server/ItemInWorldManager.java
+++ b/src/main/java/net/minecraft/server/ItemInWorldManager.java
@@ -226,20 +226,20 @@ public class ItemInWorldManager {
         int l = this.world.getTypeId(i, j, k);
         int i1 = this.world.getData(i, j, k);
 
-        this.world.a(this.player, 2001, i, j, k, l + this.world.getData(i, j, k) * 256);
+        this.world.a(this.player, 2001, i, j, k, l + (this.world.getData(i, j, k) << 12));
         boolean flag = this.b(i, j, k);
 
         if (this.isCreative()) {
             ((EntityPlayer) this.player).netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, this.world));
         } else {
-            ItemStack itemstack = this.player.Q();
+            ItemStack itemstack = this.player.T();
             boolean flag1 = this.player.b(Block.byId[l]);
 
             if (itemstack != null) {
                 itemstack.a(l, i, j, k, this.player);
                 if (itemstack.count == 0) {
                     itemstack.a(this.player);
-                    this.player.R();
+                    this.player.U();
                 }
             }
 
diff --git a/src/main/java/net/minecraft/server/ItemMonsterEgg.java b/src/main/java/net/minecraft/server/ItemMonsterEgg.java
index 8f82ce1a36..971299bc79 100644
--- a/src/main/java/net/minecraft/server/ItemMonsterEgg.java
+++ b/src/main/java/net/minecraft/server/ItemMonsterEgg.java
@@ -4,7 +4,6 @@ public class ItemMonsterEgg extends Item {
 
     public ItemMonsterEgg(int i) {
         super(i);
-        this.e(1);
         this.a(true);
     }
 
@@ -12,21 +11,38 @@ public class ItemMonsterEgg extends Item {
         if (world.isStatic || itemstack.getData() == 48 || itemstack.getData() == 49 || itemstack.getData() == 63) { // CraftBukkit
             return true;
         } else {
+            int i1 = world.getTypeId(i, j, k);
+
             i += Facing.b[l];
             j += Facing.c[l];
             k += Facing.d[l];
-            Entity entity = EntityTypes.a(itemstack.getData(), world);
+            double d0 = 0.0D;
 
-            if (entity != null && entity instanceof EntityLiving) { // CraftBukkit
-                if (!entityhuman.abilities.canInstantlyBuild) {
-                    --itemstack.count;
-                }
+            if (l == 1 && i1 == Block.FENCE.id || i1 == Block.NETHER_FENCE.id) {
+                d0 = 0.5D;
+            }
 
-                entity.setPositionRotation((double) i + 0.5D, (double) j, (double) k + 0.5D, 0.0F, 0.0F);
-                world.addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit
+            if (a(world, itemstack.getData(), (double) i + 0.5D, (double) j + d0, (double) k + 0.5D) && !entityhuman.abilities.canInstantlyBuild) {
+                --itemstack.count;
             }
 
             return true;
         }
     }
+
+    public static boolean a(World world, int i, double d0, double d1, double d2) {
+        if (!EntityTypes.a.containsKey(Integer.valueOf(i))) {
+            return false;
+        } else {
+            Entity entity = EntityTypes.a(i, world);
+
+            if (entity != null && entity instanceof EntityLiving) { // CraftBukkit
+                entity.setPositionRotation(d0, d1, d2, world.random.nextFloat() * 360.0F, 0.0F);
+                world.addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit
+                ((EntityLiving) entity).ay();
+            }
+
+            return entity != null;
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/server/ItemRedstone.java b/src/main/java/net/minecraft/server/ItemRedstone.java
index 2d1e7710e8..b9705038c5 100644
--- a/src/main/java/net/minecraft/server/ItemRedstone.java
+++ b/src/main/java/net/minecraft/server/ItemRedstone.java
@@ -58,16 +58,14 @@ public class ItemRedstone extends Item {
                 BlockPlaceEvent event = CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockState, clickedX, clickedY, clickedZ);
                 blockState.update(true);
 
+                world.suppressPhysics = false;
                 if (event.isCancelled() || !event.canBuild()) {
                     return false;
                 }
-                world.suppressPhysics = false;
-
-                world.setTypeId(i, j, k, Block.REDSTONE_WIRE.id);
-                world.update(i, j, k, Block.REDSTONE_WIRE.id); // Must take place after BlockPlaceEvent, we need to update all other blocks.
                 // CraftBukkit end
 
-                --itemstack.count; // CraftBukkit - ORDER MATTERS
+                --itemstack.count;
+                world.setTypeId(i, j, k, Block.REDSTONE_WIRE.id);
             }
 
             return true;
diff --git a/src/main/java/net/minecraft/server/ItemReed.java b/src/main/java/net/minecraft/server/ItemReed.java
index 1e667ba297..3aeaf4b66d 100644
--- a/src/main/java/net/minecraft/server/ItemReed.java
+++ b/src/main/java/net/minecraft/server/ItemReed.java
@@ -20,8 +20,8 @@ public class ItemReed extends Item {
         int i1 = world.getTypeId(i, j, k);
 
         if (i1 == Block.SNOW.id) {
-            l = 0;
-        } else if (i1 != Block.VINE.id) {
+            l = 1;
+        } else if (i1 != Block.VINE.id && i1 != Block.LONG_GRASS.id && i1 != Block.DEAD_BUSH.id) {
             if (l == 0) {
                 --j;
             }
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
index 98579af4d3..1b6d065118 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -150,7 +150,7 @@ public final class ItemStack {
     }
 
     public void setData(int i) {
-        this.damage = (this.id > 0) && (this.id < 256) ? Item.byId[this.id].filterData(i) : i; // CraftBukkit
+        this.damage = (this.id > 0) && (this.id < Block.byId.length) ? Item.byId[this.id].filterData(i) : i; // CraftBukkit
     }
 
     public int i() {
@@ -263,8 +263,8 @@ public final class ItemStack {
         Item.byId[this.id].a(this, world, entity, i, flag);
     }
 
-    public void c(World world, EntityHuman entityhuman) {
-        entityhuman.a(StatisticList.D[this.id], this.count);
+    public void a(World world, EntityHuman entityhuman, int i) {
+        entityhuman.a(StatisticList.D[this.id], i);
         Item.byId[this.id].d(this, world, entityhuman);
     }
 
@@ -280,7 +280,7 @@ public final class ItemStack {
         return this.getItem().d(this);
     }
 
-    public void a(World world, EntityHuman entityhuman, int i) {
+    public void b(World world, EntityHuman entityhuman, int i) {
         this.getItem().a(this, world, entityhuman, i);
     }
 
diff --git a/src/main/java/net/minecraft/server/ItemStep.java b/src/main/java/net/minecraft/server/ItemStep.java
index 22ee385c3a..dfbbea1614 100644
--- a/src/main/java/net/minecraft/server/ItemStep.java
+++ b/src/main/java/net/minecraft/server/ItemStep.java
@@ -23,10 +23,6 @@ public class ItemStep extends ItemBlock {
     }
 
     public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l) {
-        if (l != 1) {
-            ;
-        }
-
         if (itemstack.count == 0) {
             return false;
         } else if (!entityhuman.d(i, j, k)) {
@@ -34,8 +30,10 @@ public class ItemStep extends ItemBlock {
         } else {
             int i1 = world.getTypeId(i, j, k);
             int j1 = world.getData(i, j, k);
+            int k1 = j1 & 7;
+            boolean flag = (j1 & 8) != 0;
 
-            if (l == 1 && i1 == Block.STEP.id && j1 == itemstack.getData()) {
+            if ((l == 1 && !flag || l == 0 && flag) && i1 == Block.STEP.id && k1 == itemstack.getData()) {
                 /* CraftBukkit start - handle this in super
                 if (world.setTypeIdAndData(i, j, k, Block.DOUBLE_STEP.id, j1)) {
                     world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), Block.DOUBLE_STEP.stepSound.getName(), (Block.DOUBLE_STEP.stepSound.getVolume1() + 1.0F) / 2.0F, Block.DOUBLE_STEP.stepSound.getVolume2() * 0.8F);
diff --git a/src/main/java/net/minecraft/server/ItemWorldMap.java b/src/main/java/net/minecraft/server/ItemWorldMap.java
index ab4937c891..0e6cc64a32 100644
--- a/src/main/java/net/minecraft/server/ItemWorldMap.java
+++ b/src/main/java/net/minecraft/server/ItemWorldMap.java
@@ -48,7 +48,7 @@ public class ItemWorldMap extends ItemWorldMapBase {
             int i1 = MathHelper.floor(entity.locZ - (double) k) / i + short2 / 2;
             int j1 = 128 / i;
 
-            if (world.worldProvider.f) {
+            if (world.worldProvider.e) {
                 j1 /= 2;
             }
 
@@ -82,7 +82,7 @@ public class ItemWorldMap extends ItemWorldMapBase {
                             int l4;
                             int i5;
 
-                            if (world.worldProvider.f) {
+                            if (world.worldProvider.e) {
                                 l4 = i3 + j3 * 231871;
                                 l4 = l4 * l4 * 31287121 + l4 * 11;
                                 if ((l4 >> 20 & 1) == 0) {
@@ -106,7 +106,7 @@ public class ItemWorldMap extends ItemWorldMapBase {
                                                 j5 = chunk.getTypeId(l4 + k3, k4 - 1, j4 + l3);
                                                 if (j5 == 0) {
                                                     flag1 = false;
-                                                } else if (k4 > 0 && j5 > 0 && Block.byId[j5].material.E == MaterialMapColor.b) {
+                                                } else if (k4 > 0 && j5 > 0 && Block.byId[j5].material.F == MaterialMapColor.b) {
                                                     flag1 = false;
                                                 }
 
@@ -164,7 +164,7 @@ public class ItemWorldMap extends ItemWorldMapBase {
 
                             i5 = 0;
                             if (j4 > 0) {
-                                MaterialMapColor materialmapcolor = Block.byId[j4].material.E;
+                                MaterialMapColor materialmapcolor = Block.byId[j4].material.F;
 
                                 if (materialmapcolor == MaterialMapColor.n) {
                                     d2 = (double) i4 * 0.1D + (double) (k1 + j2 & 1) * 0.2D;
diff --git a/src/main/java/net/minecraft/server/LongHashMap.java b/src/main/java/net/minecraft/server/LongHashMap.java
deleted file mode 100644
index 0e856131dc..0000000000
--- a/src/main/java/net/minecraft/server/LongHashMap.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package net.minecraft.server;
-
-public class LongHashMap {
-
-    private transient LongHashMapEntry[] entries = new LongHashMapEntry[16];
-    private transient int count;
-    private int c = 12;
-    private final float d = 0.75F;
-    private transient volatile int e;
-
-    public LongHashMap() {}
-
-    private static int g(long i) {
-        return a((int) (i ^ i >>> 32));
-    }
-
-    private static int a(int i) {
-        i ^= i >>> 20 ^ i >>> 12;
-        return i ^ i >>> 7 ^ i >>> 4;
-    }
-
-    private static int a(int i, int j) {
-        return i & j - 1;
-    }
-
-    public int count() {
-        return this.count;
-    }
-
-    public Object getEntry(long i) {
-        int j = g(i);
-
-        for (LongHashMapEntry longhashmapentry = this.entries[a(j, this.entries.length)]; longhashmapentry != null; longhashmapentry = longhashmapentry.c) {
-            if (longhashmapentry.a == i) {
-                return longhashmapentry.b;
-            }
-        }
-
-        return null;
-    }
-
-    public boolean contains(long i) {
-        return this.c(i) != null;
-    }
-
-    final LongHashMapEntry c(long i) {
-        int j = g(i);
-
-        for (LongHashMapEntry longhashmapentry = this.entries[a(j, this.entries.length)]; longhashmapentry != null; longhashmapentry = longhashmapentry.c) {
-            if (longhashmapentry.a == i) {
-                return longhashmapentry;
-            }
-        }
-
-        return null;
-    }
-
-    public void put(long i, Object object) {
-        int j = g(i);
-        int k = a(j, this.entries.length);
-
-        for (LongHashMapEntry longhashmapentry = this.entries[k]; longhashmapentry != null; longhashmapentry = longhashmapentry.c) {
-            if (longhashmapentry.a == i) {
-                longhashmapentry.b = object;
-            }
-        }
-
-        ++this.e;
-        this.a(j, i, object, k);
-    }
-
-    private void b(int i) {
-        LongHashMapEntry[] alonghashmapentry = this.entries;
-        int j = alonghashmapentry.length;
-
-        if (j == 1073741824) {
-            this.c = Integer.MAX_VALUE;
-        } else {
-            LongHashMapEntry[] alonghashmapentry1 = new LongHashMapEntry[i];
-
-            this.a(alonghashmapentry1);
-            this.entries = alonghashmapentry1;
-            this.c = (int) ((float) i * this.d);
-        }
-    }
-
-    private void a(LongHashMapEntry[] alonghashmapentry) {
-        LongHashMapEntry[] alonghashmapentry1 = this.entries;
-        int i = alonghashmapentry.length;
-
-        for (int j = 0; j < alonghashmapentry1.length; ++j) {
-            LongHashMapEntry longhashmapentry = alonghashmapentry1[j];
-
-            if (longhashmapentry != null) {
-                alonghashmapentry1[j] = null;
-
-                LongHashMapEntry longhashmapentry1;
-
-                do {
-                    longhashmapentry1 = longhashmapentry.c;
-                    int k = a(longhashmapentry.d, i);
-
-                    longhashmapentry.c = alonghashmapentry[k];
-                    alonghashmapentry[k] = longhashmapentry;
-                    longhashmapentry = longhashmapentry1;
-                } while (longhashmapentry1 != null);
-            }
-        }
-    }
-
-    public Object remove(long i) {
-        LongHashMapEntry longhashmapentry = this.e(i);
-
-        return longhashmapentry == null ? null : longhashmapentry.b;
-    }
-
-    final LongHashMapEntry e(long i) {
-        int j = g(i);
-        int k = a(j, this.entries.length);
-        LongHashMapEntry longhashmapentry = this.entries[k];
-
-        LongHashMapEntry longhashmapentry1;
-        LongHashMapEntry longhashmapentry2;
-
-        for (longhashmapentry1 = longhashmapentry; longhashmapentry1 != null; longhashmapentry1 = longhashmapentry2) {
-            longhashmapentry2 = longhashmapentry1.c;
-            if (longhashmapentry1.a == i) {
-                ++this.e;
-                --this.count;
-                if (longhashmapentry == longhashmapentry1) {
-                    this.entries[k] = longhashmapentry2;
-                } else {
-                    longhashmapentry.c = longhashmapentry2;
-                }
-
-                return longhashmapentry1;
-            }
-
-            longhashmapentry = longhashmapentry1;
-        }
-
-        return longhashmapentry1;
-    }
-
-    private void a(int i, long j, Object object, int k) {
-        LongHashMapEntry longhashmapentry = this.entries[k];
-
-        this.entries[k] = new LongHashMapEntry(i, j, object, longhashmapentry);
-        if (this.count++ >= this.c) {
-            this.b(2 * this.entries.length);
-        }
-    }
-
-    static int f(long i) {
-        return g(i);
-    }
-}
diff --git a/src/main/java/net/minecraft/server/MinecartTrackLogic.java b/src/main/java/net/minecraft/server/MinecartTrackLogic.java
deleted file mode 100644
index aa5d8a701f..0000000000
--- a/src/main/java/net/minecraft/server/MinecartTrackLogic.java
+++ /dev/null
@@ -1,359 +0,0 @@
-package net.minecraft.server;
-
-import java.util.ArrayList;
-import java.util.List;
-
-class MinecartTrackLogic {
-
-    private World b;
-    private int c;
-    private int d;
-    private int e;
-    private final boolean f;
-    private List g;
-
-    final BlockMinecartTrack a;
-
-    public MinecartTrackLogic(BlockMinecartTrack blockminecarttrack, World world, int i, int j, int k) {
-        this.a = blockminecarttrack;
-        this.g = new ArrayList();
-        this.b = world;
-        this.c = i;
-        this.d = j;
-        this.e = k;
-        int l = world.getTypeId(i, j, k);
-        int i1 = world.getData(i, j, k);
-
-        if (BlockMinecartTrack.a((BlockMinecartTrack) Block.byId[l])) {
-            this.f = true;
-            i1 &= -9;
-        } else {
-            this.f = false;
-        }
-
-        this.a(i1);
-    }
-
-    private void a(int i) {
-        this.g.clear();
-        if (i == 0) {
-            this.g.add(new ChunkPosition(this.c, this.d, this.e - 1));
-            this.g.add(new ChunkPosition(this.c, this.d, this.e + 1));
-        } else if (i == 1) {
-            this.g.add(new ChunkPosition(this.c - 1, this.d, this.e));
-            this.g.add(new ChunkPosition(this.c + 1, this.d, this.e));
-        } else if (i == 2) {
-            this.g.add(new ChunkPosition(this.c - 1, this.d, this.e));
-            this.g.add(new ChunkPosition(this.c + 1, this.d + 1, this.e));
-        } else if (i == 3) {
-            this.g.add(new ChunkPosition(this.c - 1, this.d + 1, this.e));
-            this.g.add(new ChunkPosition(this.c + 1, this.d, this.e));
-        } else if (i == 4) {
-            this.g.add(new ChunkPosition(this.c, this.d + 1, this.e - 1));
-            this.g.add(new ChunkPosition(this.c, this.d, this.e + 1));
-        } else if (i == 5) {
-            this.g.add(new ChunkPosition(this.c, this.d, this.e - 1));
-            this.g.add(new ChunkPosition(this.c, this.d + 1, this.e + 1));
-        } else if (i == 6) {
-            this.g.add(new ChunkPosition(this.c + 1, this.d, this.e));
-            this.g.add(new ChunkPosition(this.c, this.d, this.e + 1));
-        } else if (i == 7) {
-            this.g.add(new ChunkPosition(this.c - 1, this.d, this.e));
-            this.g.add(new ChunkPosition(this.c, this.d, this.e + 1));
-        } else if (i == 8) {
-            this.g.add(new ChunkPosition(this.c - 1, this.d, this.e));
-            this.g.add(new ChunkPosition(this.c, this.d, this.e - 1));
-        } else if (i == 9) {
-            this.g.add(new ChunkPosition(this.c + 1, this.d, this.e));
-            this.g.add(new ChunkPosition(this.c, this.d, this.e - 1));
-        }
-    }
-
-    private void a() {
-        for (int i = 0; i < this.g.size(); ++i) {
-            MinecartTrackLogic minecarttracklogic = this.a((ChunkPosition) this.g.get(i));
-
-            if (minecarttracklogic != null && minecarttracklogic.b(this)) {
-                this.g.set(i, new ChunkPosition(minecarttracklogic.c, minecarttracklogic.d, minecarttracklogic.e));
-            } else {
-                this.g.remove(i--);
-            }
-        }
-    }
-
-    private boolean a(int i, int j, int k) {
-        return BlockMinecartTrack.g(this.b, i, j, k) ? true : (BlockMinecartTrack.g(this.b, i, j + 1, k) ? true : BlockMinecartTrack.g(this.b, i, j - 1, k));
-    }
-
-    private MinecartTrackLogic a(ChunkPosition chunkposition) {
-        return BlockMinecartTrack.g(this.b, chunkposition.x, chunkposition.y, chunkposition.z) ? new MinecartTrackLogic(this.a, this.b, chunkposition.x, chunkposition.y, chunkposition.z) : (BlockMinecartTrack.g(this.b, chunkposition.x, chunkposition.y + 1, chunkposition.z) ? new MinecartTrackLogic(this.a, this.b, chunkposition.x, chunkposition.y + 1, chunkposition.z) : (BlockMinecartTrack.g(this.b, chunkposition.x, chunkposition.y - 1, chunkposition.z) ? new MinecartTrackLogic(this.a, this.b, chunkposition.x, chunkposition.y - 1, chunkposition.z) : null));
-    }
-
-    private boolean b(MinecartTrackLogic minecarttracklogic) {
-        for (int i = 0; i < this.g.size(); ++i) {
-            ChunkPosition chunkposition = (ChunkPosition) this.g.get(i);
-
-            if (chunkposition.x == minecarttracklogic.c && chunkposition.z == minecarttracklogic.e) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private boolean b(int i, int j, int k) {
-        for (int l = 0; l < this.g.size(); ++l) {
-            ChunkPosition chunkposition = (ChunkPosition) this.g.get(l);
-
-            if (chunkposition.x == i && chunkposition.z == k) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private int b() {
-        int i = 0;
-
-        if (this.a(this.c, this.d, this.e - 1)) {
-            ++i;
-        }
-
-        if (this.a(this.c, this.d, this.e + 1)) {
-            ++i;
-        }
-
-        if (this.a(this.c - 1, this.d, this.e)) {
-            ++i;
-        }
-
-        if (this.a(this.c + 1, this.d, this.e)) {
-            ++i;
-        }
-
-        return i;
-    }
-
-    private boolean c(MinecartTrackLogic minecarttracklogic) {
-        if (this.b(minecarttracklogic)) {
-            return true;
-        } else if (this.g.size() == 2) {
-            return false;
-        } else if (this.g.size() == 0) {
-            return true;
-        } else {
-            ChunkPosition chunkposition = (ChunkPosition) this.g.get(0);
-
-            return minecarttracklogic.d == this.d && chunkposition.y == this.d ? true : true;
-        }
-    }
-
-    private void d(MinecartTrackLogic minecarttracklogic) {
-        this.g.add(new ChunkPosition(minecarttracklogic.c, minecarttracklogic.d, minecarttracklogic.e));
-        boolean flag = this.b(this.c, this.d, this.e - 1);
-        boolean flag1 = this.b(this.c, this.d, this.e + 1);
-        boolean flag2 = this.b(this.c - 1, this.d, this.e);
-        boolean flag3 = this.b(this.c + 1, this.d, this.e);
-        byte b0 = -1;
-
-        if (flag || flag1) {
-            b0 = 0;
-        }
-
-        if (flag2 || flag3) {
-            b0 = 1;
-        }
-
-        if (!this.f) {
-            if (flag1 && flag3 && !flag && !flag2) {
-                b0 = 6;
-            }
-
-            if (flag1 && flag2 && !flag && !flag3) {
-                b0 = 7;
-            }
-
-            if (flag && flag2 && !flag1 && !flag3) {
-                b0 = 8;
-            }
-
-            if (flag && flag3 && !flag1 && !flag2) {
-                b0 = 9;
-            }
-        }
-
-        if (b0 == 0) {
-            if (BlockMinecartTrack.g(this.b, this.c, this.d + 1, this.e - 1)) {
-                b0 = 4;
-            }
-
-            if (BlockMinecartTrack.g(this.b, this.c, this.d + 1, this.e + 1)) {
-                b0 = 5;
-            }
-        }
-
-        if (b0 == 1) {
-            if (BlockMinecartTrack.g(this.b, this.c + 1, this.d + 1, this.e)) {
-                b0 = 2;
-            }
-
-            if (BlockMinecartTrack.g(this.b, this.c - 1, this.d + 1, this.e)) {
-                b0 = 3;
-            }
-        }
-
-        if (b0 < 0) {
-            b0 = 0;
-        }
-
-        int i = b0;
-
-        if (this.f) {
-            i = this.b.getData(this.c, this.d, this.e) & 8 | b0;
-        }
-
-        this.b.setData(this.c, this.d, this.e, i);
-    }
-
-    private boolean c(int i, int j, int k) {
-        MinecartTrackLogic minecarttracklogic = this.a(new ChunkPosition(i, j, k));
-
-        if (minecarttracklogic == null) {
-            return false;
-        } else {
-            minecarttracklogic.a();
-            return minecarttracklogic.c(this);
-        }
-    }
-
-    public void a(boolean flag, boolean flag1) {
-        boolean flag2 = this.c(this.c, this.d, this.e - 1);
-        boolean flag3 = this.c(this.c, this.d, this.e + 1);
-        boolean flag4 = this.c(this.c - 1, this.d, this.e);
-        boolean flag5 = this.c(this.c + 1, this.d, this.e);
-        byte b0 = -1;
-
-        if ((flag2 || flag3) && !flag4 && !flag5) {
-            b0 = 0;
-        }
-
-        if ((flag4 || flag5) && !flag2 && !flag3) {
-            b0 = 1;
-        }
-
-        if (!this.f) {
-            if (flag3 && flag5 && !flag2 && !flag4) {
-                b0 = 6;
-            }
-
-            if (flag3 && flag4 && !flag2 && !flag5) {
-                b0 = 7;
-            }
-
-            if (flag2 && flag4 && !flag3 && !flag5) {
-                b0 = 8;
-            }
-
-            if (flag2 && flag5 && !flag3 && !flag4) {
-                b0 = 9;
-            }
-        }
-
-        if (b0 == -1) {
-            if (flag2 || flag3) {
-                b0 = 0;
-            }
-
-            if (flag4 || flag5) {
-                b0 = 1;
-            }
-
-            if (!this.f) {
-                if (flag) {
-                    if (flag3 && flag5) {
-                        b0 = 6;
-                    }
-
-                    if (flag4 && flag3) {
-                        b0 = 7;
-                    }
-
-                    if (flag5 && flag2) {
-                        b0 = 9;
-                    }
-
-                    if (flag2 && flag4) {
-                        b0 = 8;
-                    }
-                } else {
-                    if (flag2 && flag4) {
-                        b0 = 8;
-                    }
-
-                    if (flag5 && flag2) {
-                        b0 = 9;
-                    }
-
-                    if (flag4 && flag3) {
-                        b0 = 7;
-                    }
-
-                    if (flag3 && flag5) {
-                        b0 = 6;
-                    }
-                }
-            }
-        }
-
-        if (b0 == 0) {
-            if (BlockMinecartTrack.g(this.b, this.c, this.d + 1, this.e - 1)) {
-                b0 = 4;
-            }
-
-            if (BlockMinecartTrack.g(this.b, this.c, this.d + 1, this.e + 1)) {
-                b0 = 5;
-            }
-        }
-
-        if (b0 == 1) {
-            if (BlockMinecartTrack.g(this.b, this.c + 1, this.d + 1, this.e)) {
-                b0 = 2;
-            }
-
-            if (BlockMinecartTrack.g(this.b, this.c - 1, this.d + 1, this.e)) {
-                b0 = 3;
-            }
-        }
-
-        if (b0 < 0) {
-            b0 = 0;
-        }
-
-        this.a(b0);
-        int i = b0;
-
-        if (this.f) {
-            i = this.b.getData(this.c, this.d, this.e) & 8 | b0;
-        }
-
-        if (flag1 || this.b.getData(this.c, this.d, this.e) != i) {
-            this.b.setData(this.c, this.d, this.e, i);
-
-            for (int j = 0; j < this.g.size(); ++j) {
-                MinecartTrackLogic minecarttracklogic = this.a((ChunkPosition) this.g.get(j));
-
-                if (minecarttracklogic != null) {
-                    minecarttracklogic.a();
-                    if (minecarttracklogic.c(this)) {
-                        minecarttracklogic.d(this);
-                    }
-                }
-            }
-        }
-    }
-
-    static int a(MinecartTrackLogic minecarttracklogic) {
-        return minecarttracklogic.b();
-    }
-}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index be06b2c956..d7fbe2a1ea 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -40,8 +40,8 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
 
     public static Logger log = Logger.getLogger("Minecraft");
     public static HashMap trackerList = new HashMap();
-    private String t;
-    private int u;
+    private String y;
+    private int z;
     public NetworkListenThread networkListenThread;
     public PropertyManager propertyManager;
     // public WorldServer[] worldServer; // CraftBukkit - removed!
@@ -54,8 +54,8 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
     int ticks = 0;
     public String k;
     public int l;
-    private List x = new ArrayList();
-    private List y = Collections.synchronizedList(new ArrayList());
+    private List C = new ArrayList();
+    private List D = Collections.synchronizedList(new ArrayList());
     // public EntityTracker[] tracker = new EntityTracker[3]; // CraftBukkit - removed!
     public boolean onlineMode;
     public boolean spawnAnimals;
@@ -63,8 +63,17 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
     public boolean pvpMode;
     public boolean allowFlight;
     public String motd;
-    private RemoteStatusListener z;
-    private RemoteControlListener A;
+    public int t;
+    private long E;
+    private long F;
+    private long G;
+    private long H;
+    public long[] u = new long[100];
+    public long[] v = new long[100];
+    public long[] w = new long[100];
+    public long[] x = new long[100];
+    private RemoteStatusListener I;
+    private RemoteControlListener J;
 
     // CraftBukkit start
     public List<WorldServer> worlds = new ArrayList<WorldServer>();
@@ -103,7 +112,7 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
         System.setErr(new PrintStream(new LoggerOutputStream(log, Level.SEVERE), true));
         // CraftBukkit end
 
-        log.info("Starting minecraft server version 1.1");
+        log.info("Starting minecraft server version 1.2.2");
         if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
             log.warning("**** NOT ENOUGH RAM!");
             log.warning("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
@@ -111,7 +120,7 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
 
         log.info("Loading properties");
         this.propertyManager = new PropertyManager(this.options); // CraftBukkit - CLI argument support
-        this.t = this.propertyManager.getString("server-ip", "");
+        this.y = this.propertyManager.getString("server-ip", "");
         this.onlineMode = this.propertyManager.getBoolean("online-mode", true);
         this.spawnAnimals = this.propertyManager.getBoolean("spawn-animals", true);
         this.spawnNPCs = this.propertyManager.getBoolean("spawn-npcs", true);
@@ -121,15 +130,15 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
         this.motd.replace('\u00a7', '$');
         InetAddress inetaddress = null;
 
-        if (this.t.length() > 0) {
-            inetaddress = InetAddress.getByName(this.t);
+        if (this.y.length() > 0) {
+            inetaddress = InetAddress.getByName(this.y);
         }
 
-        this.u = this.propertyManager.getInt("server-port", 25565);
-        log.info("Starting Minecraft server on " + (this.t.length() == 0 ? "*" : this.t) + ":" + this.u);
+        this.z = this.propertyManager.getInt("server-port", 25565);
+        log.info("Starting Minecraft server on " + (this.y.length() == 0 ? "*" : this.y) + ":" + this.z);
 
         try {
-            this.networkListenThread = new NetworkListenThread(this, inetaddress, this.u);
+            this.networkListenThread = new NetworkListenThread(this, inetaddress, this.z);
         } catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable
             log.warning("**** FAILED TO BIND TO PORT!");
             log.log(Level.WARNING, "The exception was: " + ioexception.toString());
@@ -170,6 +179,10 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
             worldtype = WorldType.NORMAL;
         }
 
+        this.t = this.propertyManager.getInt("max-build-height", 256);
+        this.t = (this.t + 8) / 16 * 16;
+        this.t = MathHelper.a(this.t, 64, 256);
+        this.propertyManager.a("max-build-height", Integer.valueOf(this.t));
         log.info("Preparing level \"" + s + "\"");
         this.a(new WorldLoaderServer(new File(".")), s, j, worldtype);
 
@@ -181,14 +194,14 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
 
         if (this.propertyManager.getBoolean("enable-query", false)) {
             log.info("Starting GS4 status listener");
-            this.z = new RemoteStatusListener(this);
-            this.z.a();
+            this.I = new RemoteStatusListener(this);
+            this.I.a();
         }
 
         if (this.propertyManager.getBoolean("enable-rcon", false)) {
             log.info("Starting remote control listener");
-            this.A = new RemoteControlListener(this);
-            this.A.a();
+            this.J = new RemoteControlListener(this);
+            this.J.a();
             this.remoteConsole = new CraftRemoteConsoleCommandSender();
         }
 
@@ -542,8 +555,8 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
         }
         // CraftBukkit end
 
-        for (k = 0; k < this.x.size(); ++k) {
-            ((IUpdatePlayerListBox) this.x.get(k)).a();
+        for (k = 0; k < this.C.size(); ++k) {
+            ((IUpdatePlayerListBox) this.C.get(k)).a();
         }
 
         try {
@@ -553,15 +566,23 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
         }
 
         this.f[this.ticks % 100] = System.nanoTime() - i;
+        this.u[this.ticks % 100] = Packet.n - this.E;
+        this.E = Packet.n;
+        this.v[this.ticks % 100] = Packet.o - this.F;
+        this.F = Packet.o;
+        this.w[this.ticks % 100] = Packet.l - this.G;
+        this.G = Packet.l;
+        this.x[this.ticks % 100] = Packet.m - this.H;
+        this.H = Packet.m;
     }
 
     public void issueCommand(String s, ICommandListener icommandlistener) {
-        this.y.add(new ServerCommand(s, icommandlistener));
+        this.D.add(new ServerCommand(s, icommandlistener));
     }
 
     public void b() {
-        while (this.y.size() > 0) {
-            ServerCommand servercommand = (ServerCommand) this.y.remove(0);
+        while (this.D.size() > 0) {
+            ServerCommand servercommand = (ServerCommand) this.D.remove(0);
 
             // CraftBukkit start - ServerCommand for preprocessing
             ServerCommandEvent event = new ServerCommandEvent(this.console, servercommand.command);
@@ -575,7 +596,7 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
     }
 
     public void a(IUpdatePlayerListBox iupdateplayerlistbox) {
-        this.x.add(iupdateplayerlistbox);
+        this.C.add(iupdateplayerlistbox);
     }
 
     public static void main(final OptionSet options) { // CraftBukkit - replaces main(String args[])
@@ -647,11 +668,11 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
     }
 
     public String getMotd() {
-        return this.t;
+        return this.y;
     }
 
     public int getPort() {
-        return this.u;
+        return this.z;
     }
 
     public String getServerAddress() {
@@ -659,7 +680,7 @@ public class MinecraftServer implements Runnable, ICommandListener, IMinecraftSe
     }
 
     public String getVersion() {
-        return "1.1";
+        return "1.2.2";
     }
 
     public int getPlayerCount() {
diff --git a/src/main/java/net/minecraft/server/MobEffectList.java b/src/main/java/net/minecraft/server/MobEffectList.java
index 56282e95da..d0cf8e8224 100644
--- a/src/main/java/net/minecraft/server/MobEffectList.java
+++ b/src/main/java/net/minecraft/server/MobEffectList.java
@@ -95,8 +95,8 @@ public class MobEffectList {
             }
         } else if (this.id == HUNGER.id && entityliving instanceof EntityHuman) {
             ((EntityHuman) entityliving).c(0.025F * (float) (i + 1));
-        } else if ((this.id != HEAL.id || entityliving.aE()) && (this.id != HARM.id || !entityliving.aE())) {
-            if (this.id == HARM.id && !entityliving.aE() || this.id == HEAL.id && entityliving.aE()) {
+        } else if ((this.id != HEAL.id || entityliving.aM()) && (this.id != HARM.id || !entityliving.aM())) {
+            if (this.id == HARM.id && !entityliving.aM() || this.id == HEAL.id && entityliving.aM()) {
                 // CraftBukkit start
                 EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, entityliving, DamageCause.MAGIC, 6 << i);
                 Bukkit.getPluginManager().callEvent(event);
@@ -120,8 +120,8 @@ public class MobEffectList {
         // CraftBukkit end
         int j;
 
-        if ((this.id != HEAL.id || entityliving1.aE()) && (this.id != HARM.id || !entityliving1.aE())) {
-            if (this.id == HARM.id && !entityliving1.aE() || this.id == HEAL.id && entityliving1.aE()) {
+        if ((this.id != HEAL.id || entityliving1.aM()) && (this.id != HARM.id || !entityliving1.aM())) {
+            if (this.id == HARM.id && !entityliving1.aM() || this.id == HEAL.id && entityliving1.aM()) {
                 j = (int) (d0 * (double) (6 << i) + 0.5D);
 
                 // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java
index 1c8229b570..312a7fd247 100644
--- a/src/main/java/net/minecraft/server/NBTTagCompound.java
+++ b/src/main/java/net/minecraft/server/NBTTagCompound.java
@@ -99,6 +99,10 @@ public class NBTTagCompound extends NBTBase {
         this.map.put(s, new NBTTagByteArray(s, abyte));
     }
 
+    public void setIntArray(String s, int[] aint) {
+        this.map.put(s, new NBTTagIntArray(s, aint));
+    }
+
     public void setCompound(String s, NBTTagCompound nbttagcompound) {
         this.map.put(s, nbttagcompound.setName(s));
     }
@@ -147,6 +151,10 @@ public class NBTTagCompound extends NBTBase {
         return !this.map.containsKey(s) ? new byte[0] : ((NBTTagByteArray) this.map.get(s)).data;
     }
 
+    public int[] getIntArray(String s) {
+        return !this.map.containsKey(s) ? new int[0] : ((NBTTagIntArray) this.map.get(s)).data;
+    }
+
     public NBTTagCompound getCompound(String s) {
         return !this.map.containsKey(s) ? new NBTTagCompound(s) : (NBTTagCompound) this.map.get(s);
     }
diff --git a/src/main/java/net/minecraft/server/NetLoginHandler.java b/src/main/java/net/minecraft/server/NetLoginHandler.java
index bff2f3f227..a19aedc554 100644
--- a/src/main/java/net/minecraft/server/NetLoginHandler.java
+++ b/src/main/java/net/minecraft/server/NetLoginHandler.java
@@ -70,8 +70,8 @@ public class NetLoginHandler extends NetHandler {
 
     public void a(Packet1Login packet1login) {
         this.g = packet1login.name;
-        if (packet1login.a != 23) {
-            if (packet1login.a > 23) {
+        if (packet1login.a != 28) {
+            if (packet1login.a > 28) {
                 this.disconnect("Outdated server!");
             } else {
                 this.disconnect("Outdated client!");
@@ -111,7 +111,7 @@ public class NetLoginHandler extends NetHandler {
             if (maxPlayers > 60) {
                 maxPlayers = 60;
             }
-            netserverhandler.sendPacket(new Packet1Login("", entityplayer.id, worldserver.getSeed(), worldserver.getWorldData().getType(), entityplayer.itemInWorldManager.getGameMode(), (byte) worldserver.worldProvider.dimension, (byte) worldserver.difficulty, (byte) worldserver.height, (byte) maxPlayers));
+            netserverhandler.sendPacket(new Packet1Login("", entityplayer.id, worldserver.getWorldData().getType(), entityplayer.itemInWorldManager.getGameMode(), worldserver.worldProvider.dimension, (byte) worldserver.difficulty, (byte) worldserver.getHeight(), (byte) this.server.serverConfigurationManager.getMaxPlayers()));
             entityplayer.getBukkitEntity().sendSupportedChannels();
             // CraftBukkit end
 
diff --git a/src/main/java/net/minecraft/server/NetServerHandler.java b/src/main/java/net/minecraft/server/NetServerHandler.java
index 8f27a7ee26..b6e41be883 100644
--- a/src/main/java/net/minecraft/server/NetServerHandler.java
+++ b/src/main/java/net/minecraft/server/NetServerHandler.java
@@ -62,11 +62,12 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
     private static Random k = new Random();
     private long l;
     private int m = 0;
-    private double x;
+    private int x = 0;
     private double y;
     private double z;
+    private double q;
     private boolean checkMovement = true;
-    private IntHashMap r = new IntHashMap();
+    private IntHashMap s = new IntHashMap();
 
     public NetServerHandler(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
         this.minecraftServer = minecraftserver;
@@ -119,6 +120,10 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
         if (this.m > 0) {
             --this.m;
         }
+
+        if (this.x > 0) {
+            --this.x;
+        }
     }
 
     public void disconnect(String s) {
@@ -137,7 +142,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
             s = event.getReason();
             // CraftBukkit end
 
-            this.player.F();
+            this.player.I();
             this.sendPacket(new Packet255KickDisconnect(s));
             this.networkManager.d();
 
@@ -162,8 +167,8 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
             double d0;
 
             if (!this.checkMovement) {
-                d0 = packet10flying.y - this.y;
-                if (packet10flying.x == this.x && d0 * d0 < 0.01D && packet10flying.z == this.z) {
+                d0 = packet10flying.y - this.z;
+                if (packet10flying.x == this.y && d0 * d0 < 0.01D && packet10flying.z == this.q) {
                     this.checkMovement = true;
                 }
             }
@@ -243,7 +248,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                     float f = this.player.yaw;
                     float f1 = this.player.pitch;
 
-                    this.player.vehicle.i();
+                    this.player.vehicle.i_();
                     d1 = this.player.locX;
                     d2 = this.player.locY;
                     d3 = this.player.locZ;
@@ -278,28 +283,28 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                     }
 
                     if (this.player.vehicle != null) {
-                        this.player.vehicle.i();
+                        this.player.vehicle.i_();
                     }
 
                     this.minecraftServer.serverConfigurationManager.d(this.player);
-                    this.x = this.player.locX;
-                    this.y = this.player.locY;
-                    this.z = this.player.locZ;
+                    this.y = this.player.locX;
+                    this.z = this.player.locY;
+                    this.q = this.player.locZ;
                     worldserver.playerJoinedWorld(this.player);
                     return;
                 }
 
                 if (this.player.isSleeping()) {
                     this.player.a(true);
-                    this.player.setLocation(this.x, this.y, this.z, this.player.yaw, this.player.pitch);
+                    this.player.setLocation(this.y, this.z, this.q, this.player.yaw, this.player.pitch);
                     worldserver.playerJoinedWorld(this.player);
                     return;
                 }
 
                 d0 = this.player.locY;
-                this.x = this.player.locX;
-                this.y = this.player.locY;
-                this.z = this.player.locZ;
+                this.y = this.player.locX;
+                this.z = this.player.locY;
+                this.q = this.player.locZ;
                 d1 = this.player.locX;
                 d2 = this.player.locY;
                 d3 = this.player.locZ;
@@ -334,7 +339,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
 
                 this.player.a(true);
                 this.player.bO = 0.0F;
-                this.player.setLocation(this.x, this.y, this.z, f2, f3);
+                this.player.setLocation(this.y, this.z, this.q, f2, f3);
                 if (!this.checkMovement) {
                     return;
                 }
@@ -383,7 +388,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                 boolean flag2 = worldserver.getCubes(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0;
 
                 if (flag && (flag1 || !flag2) && !this.player.isSleeping()) {
-                    this.a(this.x, this.y, this.z, f2, f3);
+                    this.a(this.y, this.z, this.q, f2, f3);
                     return;
                 }
 
@@ -452,9 +457,9 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
         // CraftBukkit end
 
         this.checkMovement = false;
-        this.x = d0;
-        this.y = d1;
-        this.z = d2;
+        this.y = d0;
+        this.z = d1;
+        this.q = d2;
         this.player.setLocation(d0, d1, d2, f, f1);
         this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(d0, d1 + 1.6200000047683716D, d1, d2, f, f1, false));
     }
@@ -480,9 +485,9 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                 }
             }
             // CraftBukkit end
-            this.player.O();
+            this.player.R();
         } else if (packet14blockdig.e == 5) {
-            this.player.J();
+            this.player.M();
         } else {
             boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
             boolean flag1 = false;
@@ -508,6 +513,10 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                 if (d3 > 36.0D) {
                     return;
                 }
+
+                if (j >= this.minecraftServer.t) {
+                    return;
+                }
             }
 
             ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
@@ -577,7 +586,12 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
         // CraftBukkit end
 
         ItemStack itemstack = this.player.inventory.getItemInHand();
-        boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
+        boolean flag = false;
+        int i = packet15place.a;
+        int j = packet15place.b;
+        int k = packet15place.c;
+        int l = packet15place.face;
+        boolean flag1 = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
 
         if (packet15place.face == 255) {
             if (itemstack == null) {
@@ -596,11 +610,10 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
             // inventory update packet to get sent
             always = (itemstack.count != itemstackAmount);
             // CraftBukkit end
+        } else if (packet15place.b >= this.minecraftServer.t - 1 && (packet15place.face == 1 || packet15place.b >= this.minecraftServer.t)) {
+            this.player.netServerHandler.sendPacket(new Packet3Chat("\u00A77Height limit for building is " + this.minecraftServer.t));
+            flag = true;
         } else {
-            int i = packet15place.a;
-            int j = packet15place.b;
-            int k = packet15place.c;
-            int l = packet15place.face;
             ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
             int i1 = MathHelper.a(i - chunkcoordinates.x);
             int j1 = MathHelper.a(k - chunkcoordinates.z);
@@ -614,13 +627,17 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
             if (Math.pow(eyeLoc.getX() - i, 2) + Math.pow(eyeLoc.getY() - j, 2) + Math.pow(eyeLoc.getZ() - k, 2) > PLACE_DISTANCE_SQUARED) {
                 return;
             }
-            flag = true; // spawn protection moved to ItemBlock!!!
+            flag1 = true; // spawn protection moved to ItemBlock!!!
             // CraftBukkit end
 
-            if (j1 > 16 || flag) {
+            if (j1 > 16 || flag1) {
                 this.player.itemInWorldManager.interact(this.player, worldserver, itemstack, i, j, k, l);
             }
 
+            flag = true;
+        }
+
+        if (flag) {
             this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
             if (l == 0) {
                 --j;
@@ -734,7 +751,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
             s = s.trim();
 
             for (int i = 0; i < s.length(); ++i) {
-                if (SharedConstants.allowedCharacters.indexOf(s.charAt(i)) < 0 && s.charAt(i) < 32) {
+                if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) {
                     this.disconnect("Illegal characters in chat");
                     return;
                 }
@@ -876,7 +893,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
             if (event.isCancelled()) return;
             // CraftBukkit end
 
-            this.player.s_();
+            this.player.D();
         }
     }
 
@@ -942,36 +959,45 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
         WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
         Entity entity = worldserver.getEntity(packet7useentity.target);
 
-        if (entity != null && this.player.g(entity) && this.player.i(entity) < 36.0D) {
-            ItemStack itemInHand = this.player.inventory.getItemInHand(); // CraftBukkit
-            if (packet7useentity.action == 0) {
-                // CraftBukkit start
-                PlayerInteractEntityEvent event = new PlayerInteractEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity());
-                this.server.getPluginManager().callEvent(event);
+        if (entity != null) {
+            boolean flag = this.player.h(entity);
+            double d0 = 36.0D;
 
-                if (event.isCancelled()) {
-                    return;
-                }
-                // CraftBukkit end
-                this.player.e(entity);
-                // CraftBukkit start - update the client if the item is an infinite one
-                if (itemInHand != null && itemInHand.count <= -1) {
-                    this.player.updateInventory(this.player.activeContainer);
-                }
-            } else if (packet7useentity.action == 1) {
-                if ((entity instanceof EntityItem) || (entity instanceof EntityExperienceOrb) || (entity instanceof EntityArrow)) {
-                    String type = entity.getClass().getSimpleName();
-                    disconnect("Attacking an " + type + " is not permitted");
-                    System.out.println("Player " + player.name + " tried to attack an " + type + ", so I have disconnected them for exploiting.");
-                    return;
-                }
+            if (!flag) {
+                d0 = 9.0D;
+            }
 
-                this.player.attack(entity);
+            if (this.player.j(entity) < d0) {
+                ItemStack itemInHand = this.player.inventory.getItemInHand(); // CraftBukkit
+                if (packet7useentity.action == 0) {
+                    // CraftBukkit start
+                    PlayerInteractEntityEvent event = new PlayerInteractEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity());
+                    this.server.getPluginManager().callEvent(event);
 
-                if (itemInHand != null && itemInHand.count <= -1) {
-                    this.player.updateInventory(this.player.activeContainer);
+                    if (event.isCancelled()) {
+                        return;
+                    }
+                    // CraftBukkit end
+                    this.player.e(entity);
+                    // CraftBukkit start - update the client if the item is an infinite one
+                    if (itemInHand != null && itemInHand.count <= -1) {
+                        this.player.updateInventory(this.player.activeContainer);
+                    }
+                } else if (packet7useentity.action == 1) {
+                    if ((entity instanceof EntityItem) || (entity instanceof EntityExperienceOrb) || (entity instanceof EntityArrow)) {
+                        String type = entity.getClass().getSimpleName();
+                        disconnect("Attacking an " + type + " is not permitted");
+                        System.out.println("Player " + player.name + " tried to attack an " + type + ", so I have disconnected them for exploiting.");
+                        return;
+                    }
+
+                    this.player.attack(entity);
+
+                    if (itemInHand != null && itemInHand.count <= -1) {
+                        this.player.updateInventory(this.player.activeContainer);
+                    }
+                    // CraftBukkit end
                 }
-                // CraftBukkit end
             }
         }
     }
@@ -1006,7 +1032,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
         this.player.activeContainer.transferTo(this.player.defaultContainer, getPlayer());
         // CraftBukkit end
 
-        this.player.E();
+        this.player.H();
     }
 
     public void a(Packet102WindowClick packet102windowclick) {
@@ -1065,7 +1091,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                 this.player.broadcastCarriedItem();
                 this.player.h = false;
             } else {
-                this.r.a(this.player.activeContainer.windowId, Short.valueOf(packet102windowclick.d));
+                this.s.a(this.player.activeContainer.windowId, Short.valueOf(packet102windowclick.d));
                 this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, false));
                 this.player.activeContainer.a(this.player, false);
                 ArrayList arraylist = new ArrayList();
@@ -1148,15 +1174,20 @@ public class NetServerHandler extends NetHandler implements ICommandListener {
                 }
 
                 this.player.defaultContainer.a(this.player, true);
-            } else if (flag && flag2 && flag3) {
-                this.player.drop(itemstack);
+            } else if (flag && flag2 && flag3 && this.x < 200) {
+                this.x += 20;
+                EntityItem entityitem = this.player.drop(itemstack);
+
+                if (entityitem != null) {
+                    entityitem.k();
+                }
             }
         }
     }
 
     public void a(Packet106Transaction packet106transaction) {
         if (this.player.dead) return; // CraftBukkit
-        Short oshort = (Short) this.r.get(this.player.activeContainer.windowId);
+        Short oshort = (Short) this.s.get(this.player.activeContainer.windowId);
 
         if (oshort != null && packet106transaction.b == oshort.shortValue() && this.player.activeContainer.windowId == packet106transaction.a && !this.player.activeContainer.c(this.player)) {
             this.player.activeContainer.a(this.player, true);
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index aad4c12aa4..a3d4d396d1 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -25,7 +25,7 @@ public class NetworkManager {
     private List highPriorityQueue = Collections.synchronizedList(new ArrayList());
     private List lowPriorityQueue = Collections.synchronizedList(new ArrayList());
     private NetHandler packetListener;
-    private boolean synched = false;
+    private boolean q = false;
     private Thread r;
     private Thread s;
     private boolean t = false;
@@ -74,7 +74,7 @@ public class NetworkManager {
     }
 
     public void queue(Packet packet) {
-        if (!this.synched) {
+        if (!this.q) {
             Object object = this.g;
 
             synchronized (this.g) {
@@ -153,7 +153,10 @@ public class NetworkManager {
                 int i = packet.b();
 
                 aint[i] += packet.a() + 1;
-                this.m.add(packet);
+                if (!this.q) {
+                    this.m.add(packet);
+                }
+
                 flag = true;
             } else {
                 this.a("disconnect.endOfStream", new Object[0]);
@@ -223,7 +226,7 @@ public class NetworkManager {
         while (!this.m.isEmpty() && i-- >= 0) {
             Packet packet = (Packet) this.m.remove(0);
 
-            if (!this.synched) packet.handle(this.packetListener); // CraftBukkit
+            if (!this.q) packet.handle(this.packetListener); // CraftBukkit
         }
 
         this.a();
@@ -237,9 +240,9 @@ public class NetworkManager {
     }
 
     public void d() {
-        if (!this.synched) {
+        if (!this.q) {
             this.a();
-            this.synched = true;
+            this.q = true;
             this.s.interrupt();
             (new NetworkMonitorThread(this)).start();
         }
@@ -258,7 +261,7 @@ public class NetworkManager {
     }
 
     static boolean b(NetworkManager networkmanager) {
-        return networkmanager.synched;
+        return networkmanager.q;
     }
 
     static boolean c(NetworkManager networkmanager) {
diff --git a/src/main/java/net/minecraft/server/Packet.java b/src/main/java/net/minecraft/server/Packet.java
index 87ae66908f..1026667e23 100644
--- a/src/main/java/net/minecraft/server/Packet.java
+++ b/src/main/java/net/minecraft/server/Packet.java
@@ -16,6 +16,10 @@ public abstract class Packet {
     private static Set b = new HashSet();
     private static Set c = new HashSet();
     public final long timestamp = System.currentTimeMillis();
+    public static long l;
+    public static long m;
+    public static long n;
+    public static long o;
     public boolean lowPriority = false;
 
     public Packet() {}
@@ -77,6 +81,8 @@ public abstract class Packet {
             }
 
             packet.a(datainputstream);
+            ++l;
+            m += (long) packet.a();
         } catch (EOFException eofexception) {
             System.out.println("Reached end of stream");
             return null;
@@ -93,6 +99,8 @@ public abstract class Packet {
         // CraftBukkit end
 
         PacketCounter.a(i, (long) packet.a());
+        ++l;
+        m += (long) packet.a();
         return packet;
     }
 
@@ -100,6 +108,8 @@ public abstract class Packet {
     public static void a(Packet packet, DataOutputStream dataoutputstream) throws IOException {
         dataoutputstream.write(packet.b());
         packet.a(dataoutputstream);
+        ++n;
+        o += (long) packet.a();
     }
 
     // CraftBukkit - throws IOException
@@ -228,6 +238,7 @@ public abstract class Packet {
         a(32, true, false, Packet32EntityLook.class);
         a(33, true, false, Packet33RelEntityMoveLook.class);
         a(34, true, false, Packet34EntityTeleport.class);
+        a(35, true, false, Packet35EntityHeadRotation.class);
         a(38, true, false, Packet38EntityStatus.class);
         a(39, true, false, Packet39AttachEntity.class);
         a(40, true, false, Packet40EntityMetadata.class);
@@ -254,6 +265,7 @@ public abstract class Packet {
         a(108, false, true, Packet108ButtonClick.class);
         a(130, true, true, Packet130UpdateSign.class);
         a(131, true, false, Packet131ItemData.class);
+        a(132, true, false, Packet132TileEntityData.class);
         a(200, true, false, Packet200Statistic.class);
         a(201, true, false, Packet201PlayerInfo.class);
         a(250, true, true, Packet250CustomPayload.class);
diff --git a/src/main/java/net/minecraft/server/Packet1Login.java b/src/main/java/net/minecraft/server/Packet1Login.java
deleted file mode 100644
index 0c4202cd8b..0000000000
--- a/src/main/java/net/minecraft/server/Packet1Login.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package net.minecraft.server;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException; // CraftBukkit
-
-public class Packet1Login extends Packet {
-
-    public int a;
-    public String name;
-    public long c;
-    public WorldType d;
-    public int e;
-    public byte f;
-    public byte g;
-    public byte h;
-    public byte i;
-
-    public Packet1Login() {}
-
-    public Packet1Login(String s, int i, long j, WorldType worldtype, int k, byte b0, byte b1, byte b2, byte b3) {
-        this.name = s;
-        this.a = i;
-        this.c = j;
-        this.d = worldtype;
-        this.f = b0;
-        this.g = b1;
-        this.e = k;
-        this.h = b2;
-        this.i = b3;
-    }
-
-    public void a(DataInputStream datainputstream) throws IOException { // CraftBukkit
-        this.a = datainputstream.readInt();
-        this.name = a(datainputstream, 16);
-        if (this.a < 23) return; // CraftBukkit
-        this.c = datainputstream.readLong();
-        String s = a(datainputstream, 16);
-
-        this.d = WorldType.getType(s);
-        if (this.d == null) {
-            this.d = WorldType.NORMAL;
-        }
-
-        this.e = datainputstream.readInt();
-        this.f = datainputstream.readByte();
-        this.g = datainputstream.readByte();
-        this.h = datainputstream.readByte();
-        this.i = datainputstream.readByte();
-    }
-
-    public void a(DataOutputStream dataoutputstream) throws IOException { // CraftBukkit
-        dataoutputstream.writeInt(this.a);
-        a(this.name, dataoutputstream);
-        dataoutputstream.writeLong(this.c);
-        if (this.d == null) {
-            a("", dataoutputstream);
-        } else {
-            a(this.d.name(), dataoutputstream);
-        }
-
-        dataoutputstream.writeInt(this.e);
-        dataoutputstream.writeByte(this.f);
-        dataoutputstream.writeByte(this.g);
-        dataoutputstream.writeByte(this.h);
-        dataoutputstream.writeByte(this.i);
-    }
-
-    public void handle(NetHandler nethandler) {
-        nethandler.a(this);
-    }
-
-    public int a() {
-        int i = 0;
-
-        if (this.d != null) {
-            i = this.d.name().length();
-        }
-
-        return 4 + this.name.length() + 4 + 7 + 4 + i;
-    }
-}
diff --git a/src/main/java/net/minecraft/server/Packet51MapChunk.java b/src/main/java/net/minecraft/server/Packet51MapChunk.java
index 3acdba76c3..08c1df815a 100644
--- a/src/main/java/net/minecraft/server/Packet51MapChunk.java
+++ b/src/main/java/net/minecraft/server/Packet51MapChunk.java
@@ -13,61 +13,155 @@ public class Packet51MapChunk extends Packet {
     public int b;
     public int c;
     public int d;
-    public int e;
-    public int f;
     public byte[] buffer;
+    public boolean f;
     public int size; // CraftBukkit - private -> public
-    public byte[] rawData; // CraftBukkit
+    private int h;
+    public byte[] rawData = new byte[0]; // CraftBukkit
 
     public Packet51MapChunk() {
         this.lowPriority = true;
     }
 
     // CraftBukkit start
-    public Packet51MapChunk(int i, int j, int k, int l, int i1, int j1, World world) {
-        this(i, j, k, l, i1, j1, world.getMultiChunkData(i, j, k, l, i1, j1));
-    }
-
-    public Packet51MapChunk(int i, int j, int k, int l, int i1, int j1, byte[] data) {
-        // CraftBukkit end
+    public Packet51MapChunk(Chunk chunk, boolean flag, int i) {
         this.lowPriority = true;
-        this.a = i;
-        this.b = j;
-        this.c = k;
-        this.d = l;
-        this.e = i1;
-        this.f = j1;
+        this.a = chunk.x;
+        this.b = chunk.z;
+        this.f = flag;
+        if (flag) {
+            i = '\uffff';
+        }
+
+        ChunkSection[] achunksection = chunk.h();
+        int j = 0;
+        int k = 0;
+
+        int l;
+
+        for (l = 0; l < achunksection.length; ++l) {
+            if (achunksection[l] != null && (!flag || !achunksection[l].a()) && (i & 1 << l) != 0) {
+                this.c |= 1 << l;
+                ++j;
+                if (achunksection[l].h() != null) {
+                    this.d |= 1 << l;
+                    ++k;
+                }
+            }
+        }
+
+        l = 2048 * (5 * j + k);
+        if (flag) {
+            l += 256;
+        }
+
+        if (rawData.length < l) {
+            rawData = new byte[l];
+        }
+
+        byte[] abyte = rawData;
+        int i1 = 0;
+
+        int j1;
+
+        for (j1 = 0; j1 < achunksection.length; ++j1) {
+            if (achunksection[j1] != null && (!flag || !achunksection[j1].a()) && (i & 1 << j1) != 0) {
+                byte[] abyte1 = achunksection[j1].g();
+
+                System.arraycopy(abyte1, 0, abyte, i1, abyte1.length);
+                i1 += abyte1.length;
+            }
+        }
+
+        NibbleArray nibblearray;
+
+        for (j1 = 0; j1 < achunksection.length; ++j1) {
+            if (achunksection[j1] != null && (!flag || !achunksection[j1].a()) && (i & 1 << j1) != 0) {
+                nibblearray = achunksection[j1].i();
+                System.arraycopy(nibblearray.a, 0, abyte, i1, nibblearray.a.length);
+                i1 += nibblearray.a.length;
+            }
+        }
+
+        for (j1 = 0; j1 < achunksection.length; ++j1) {
+            if (achunksection[j1] != null && (!flag || !achunksection[j1].a()) && (i & 1 << j1) != 0) {
+                nibblearray = achunksection[j1].j();
+                System.arraycopy(nibblearray.a, 0, abyte, i1, nibblearray.a.length);
+                i1 += nibblearray.a.length;
+            }
+        }
+
+        for (j1 = 0; j1 < achunksection.length; ++j1) {
+            if (achunksection[j1] != null && (!flag || !achunksection[j1].a()) && (i & 1 << j1) != 0) {
+                nibblearray = achunksection[j1].k();
+                System.arraycopy(nibblearray.a, 0, abyte, i1, nibblearray.a.length);
+                i1 += nibblearray.a.length;
+            }
+        }
+
+        if (k > 0) {
+            for (j1 = 0; j1 < achunksection.length; ++j1) {
+                if (achunksection[j1] != null && (!flag || !achunksection[j1].a()) && achunksection[j1].h() != null && (i & 1 << j1) != 0) {
+                    nibblearray = achunksection[j1].h();
+                    System.arraycopy(nibblearray.a, 0, abyte, i1, nibblearray.a.length);
+                    i1 += nibblearray.a.length;
+                }
+            }
+        }
+
+        if (flag) {
+            byte[] abyte2 = chunk.l();
+
+            System.arraycopy(abyte2, 0, abyte, i1, abyte2.length);
+            i1 += abyte2.length;
+        }
+
         /* CraftBukkit start - Moved compression into its own method.
         byte[] abyte = data; // CraftBukkit - uses data from above constructor
         Deflater deflater = new Deflater(-1);
 
         try {
-            deflater.setInput(abyte);
+            deflater.setInput(abyte, 0, i1);
             deflater.finish();
-            this.buffer = new byte[l * i1 * j1 * 5 / 2];
+            this.buffer = new byte[i1];
             this.size = deflater.deflate(this.buffer);
         } finally {
             deflater.end();
         } */
-        this.rawData = data;
+        this.rawData = abyte;
         // CraftBukkit end
     }
 
     public void a(DataInputStream datainputstream) throws IOException { // CraftBukkit - throws IOEXception
         this.a = datainputstream.readInt();
-        this.b = datainputstream.readShort();
-        this.c = datainputstream.readInt();
-        this.d = datainputstream.read() + 1;
-        this.e = datainputstream.read() + 1;
-        this.f = datainputstream.read() + 1;
+        this.b = datainputstream.readInt();
+        this.f = datainputstream.readBoolean();
+        this.c = datainputstream.readShort();
+        this.d = datainputstream.readShort();
         this.size = datainputstream.readInt();
-        byte[] abyte = new byte[this.size];
+        this.h = datainputstream.readInt();
+        if (rawData.length < this.size) {
+            rawData = new byte[this.size];
+        }
 
-        datainputstream.readFully(abyte);
-        this.buffer = new byte[this.d * this.e * this.f * 5 / 2];
+        datainputstream.readFully(rawData, 0, this.size);
+        int i = 0;
+
+        int j;
+
+        for (j = 0; j < 16; ++j) {
+            i += this.c >> j & 1;
+        }
+
+        j = 12288 * i;
+        if (this.f) {
+            j += 256;
+        }
+
+        this.buffer = new byte[j];
         Inflater inflater = new Inflater();
 
-        inflater.setInput(abyte);
+        inflater.setInput(rawData, 0, this.size);
 
         try {
             inflater.inflate(this.buffer);
@@ -80,12 +174,12 @@ public class Packet51MapChunk extends Packet {
 
     public void a(DataOutputStream dataoutputstream) throws IOException { // CraftBukkit - throws IOException
         dataoutputstream.writeInt(this.a);
-        dataoutputstream.writeShort(this.b);
-        dataoutputstream.writeInt(this.c);
-        dataoutputstream.write(this.d - 1);
-        dataoutputstream.write(this.e - 1);
-        dataoutputstream.write(this.f - 1);
+        dataoutputstream.writeInt(this.b);
+        dataoutputstream.writeBoolean(this.f);
+        dataoutputstream.writeShort((short) (this.c & '\uffff'));
+        dataoutputstream.writeShort((short) (this.d & '\uffff'));
         dataoutputstream.writeInt(this.size);
+        dataoutputstream.writeInt(this.h);
         dataoutputstream.write(this.buffer, 0, this.size);
     }
 
diff --git a/src/main/java/net/minecraft/server/PlayerInstance.java b/src/main/java/net/minecraft/server/PlayerInstance.java
index 295297b439..1c2ac79a22 100644
--- a/src/main/java/net/minecraft/server/PlayerInstance.java
+++ b/src/main/java/net/minecraft/server/PlayerInstance.java
@@ -12,18 +12,13 @@ class PlayerInstance {
     private short[] dirtyBlocks;
     private int dirtyCount;
     private int h;
-    private int i;
-    private int j;
-    private int k;
-    private int l;
-    private int m;
 
     final PlayerManager playerManager;
 
     public PlayerInstance(PlayerManager playermanager, int i, int j) {
         this.playerManager = playermanager;
         this.b = new ArrayList();
-        this.dirtyBlocks = new short[10];
+        this.dirtyBlocks = new short[64];
         this.dirtyCount = 0;
         this.chunkX = i;
         this.chunkZ = j;
@@ -71,36 +66,10 @@ class PlayerInstance {
     public void a(int i, int j, int k) {
         if (this.dirtyCount == 0) {
             PlayerManager.b(this.playerManager).add(this);
-            this.h = this.i = i;
-            this.j = this.k = j;
-            this.l = this.m = k;
         }
 
-        if (this.h > i) {
-            this.h = i;
-        }
-
-        if (this.i < i) {
-            this.i = i;
-        }
-
-        if (this.j > j) {
-            this.j = j;
-        }
-
-        if (this.k < j) {
-            this.k = j;
-        }
-
-        if (this.l > k) {
-            this.l = k;
-        }
-
-        if (this.m < k) {
-            this.m = k;
-        }
-
-        if (this.dirtyCount < 10) {
+        this.h |= 1 << (j >> 4);
+        if (this.dirtyCount < 64) {
             short short1 = (short) (i << 12 | k << 8 | j);
 
             for (int l = 0; l < this.dirtyCount; ++l) {
@@ -117,7 +86,7 @@ class PlayerInstance {
         for (int i = 0; i < this.b.size(); ++i) {
             EntityPlayer entityplayer = (EntityPlayer) this.b.get(i);
 
-            if (entityplayer.playerChunkCoordIntPairs.contains(this.location)) {
+            if (entityplayer.playerChunkCoordIntPairs.contains(this.location) && !entityplayer.chunkCoordIntPairQueue.contains(this.location)) {
                 entityplayer.netServerHandler.sendPacket(packet);
             }
         }
@@ -132,31 +101,30 @@ class PlayerInstance {
             int k;
 
             if (this.dirtyCount == 1) {
-                i = this.chunkX * 16 + this.h;
-                j = this.j;
-                k = this.chunkZ * 16 + this.l;
+                i = this.chunkX * 16 + (this.dirtyBlocks[0] >> 12 & 15);
+                j = this.dirtyBlocks[0] & 255;
+                k = this.chunkZ * 16 + (this.dirtyBlocks[0] >> 8 & 15);
                 this.sendAll(new Packet53BlockChange(i, j, k, worldserver));
-                if (Block.isTileEntity[worldserver.getTypeId(i, j, k)]) {
+                if (worldserver.isTileEntity(i, j, k)) {
                     this.sendTileEntity(worldserver.getTileEntity(i, j, k));
                 }
             } else {
                 int l;
 
-                if (this.dirtyCount == 10) {
-                    this.j = this.j / 2 * 2;
-                    this.k = (this.k / 2 + 1) * 2;
-                    i = this.h + this.chunkX * 16;
-                    j = this.j;
-                    k = this.l + this.chunkZ * 16;
-                    l = this.i - this.h + 1;
-                    int i1 = this.k - this.j + 2;
-                    int j1 = this.m - this.l + 1;
+                if (this.dirtyCount == 64) {
+                    i = this.chunkX * 16;
+                    j = this.chunkZ * 16;
+                    this.sendAll(new Packet51MapChunk(worldserver.getChunkAt(this.chunkX, this.chunkZ), false, this.h));
 
-                    this.sendAll(new Packet51MapChunk(i, j, k, l, i1, j1, worldserver));
-                    List list = worldserver.getTileEntities(i, j, k, i + l, j + i1, k + j1);
+                    for (k = 0; k < 16; ++k) {
+                        if ((this.h & 1 << k) != 0) {
+                            l = k << 4;
+                            List list = worldserver.getTileEntities(i, l, j, i + 16, l + 16, j + 16);
 
-                    for (int k1 = 0; k1 < list.size(); ++k1) {
-                        this.sendTileEntity((TileEntity) list.get(k1));
+                            for (int i1 = 0; i1 < list.size(); ++i1) {
+                                this.sendTileEntity((TileEntity) list.get(i1));
+                            }
+                        }
                     }
                 } else {
                     this.sendAll(new Packet52MultiBlockChange(this.chunkX, this.chunkZ, this.dirtyBlocks, this.dirtyCount, worldserver));
@@ -165,7 +133,7 @@ class PlayerInstance {
                         j = this.chunkX * 16 + (this.dirtyBlocks[i] >> 12 & 15);
                         k = this.dirtyBlocks[i] & 255;
                         l = this.chunkZ * 16 + (this.dirtyBlocks[i] >> 8 & 15);
-                        if (Block.isTileEntity[worldserver.getTypeId(j, k, l)]) {
+                        if (worldserver.isTileEntity(j, k, l)) {
                             this.sendTileEntity(worldserver.getTileEntity(j, k, l));
                         }
                     }
@@ -173,12 +141,13 @@ class PlayerInstance {
             }
 
             this.dirtyCount = 0;
+            this.h = 0;
         }
     }
 
     private void sendTileEntity(TileEntity tileentity) {
         if (tileentity != null) {
-            Packet packet = tileentity.k();
+            Packet packet = tileentity.d();
 
             if (packet != null) {
                 this.sendAll(packet);
diff --git a/src/main/java/net/minecraft/server/PlayerInventory.java b/src/main/java/net/minecraft/server/PlayerInventory.java
index 82c5bf6028..1881d7327e 100644
--- a/src/main/java/net/minecraft/server/PlayerInventory.java
+++ b/src/main/java/net/minecraft/server/PlayerInventory.java
@@ -58,7 +58,7 @@ public class PlayerInventory implements IInventory {
         return 9;
     }
 
-    private int e(int i) {
+    private int f(int i) {
         for (int j = 0; j < this.items.length; ++j) {
             if (this.items[j] != null && this.items[j].id == i) {
                 return j;
@@ -166,8 +166,8 @@ public class PlayerInventory implements IInventory {
         }
     }
 
-    public boolean b(int i) {
-        int j = this.e(i);
+    public boolean c(int i) {
+        int j = this.f(i);
 
         if (j < 0) {
             return false;
@@ -180,8 +180,8 @@ public class PlayerInventory implements IInventory {
         }
     }
 
-    public boolean c(int i) {
-        int j = this.e(i);
+    public boolean d(int i) {
+        int j = this.f(i);
 
         return j >= 0;
     }
@@ -245,6 +245,24 @@ public class PlayerInventory implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        ItemStack[] aitemstack = this.items;
+
+        if (i >= this.items.length) {
+            aitemstack = this.armor;
+            i -= this.items.length;
+        }
+
+        if (aitemstack[i] != null) {
+            ItemStack itemstack = aitemstack[i];
+
+            aitemstack[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         ItemStack[] aitemstack = this.items;
 
@@ -328,7 +346,7 @@ public class PlayerInventory implements IInventory {
     }
 
     public String getName() {
-        return "Inventory";
+        return "container.inventory";
     }
 
     public int getMaxStackSize() {
@@ -371,7 +389,7 @@ public class PlayerInventory implements IInventory {
         return i;
     }
 
-    public void d(int i) {
+    public void e(int i) {
         i /= 4;
         if (i < 1) {
             i = 1;
@@ -420,7 +438,7 @@ public class PlayerInventory implements IInventory {
     }
 
     public boolean a(EntityHuman entityhuman) {
-        return this.player.dead ? false : entityhuman.i(this.player) <= 64.0D;
+        return this.player.dead ? false : entityhuman.j(this.player) <= 64.0D;
     }
 
     public boolean c(ItemStack itemstack) {
diff --git a/src/main/java/net/minecraft/server/PortalTravelAgent.java b/src/main/java/net/minecraft/server/PortalTravelAgent.java
index ad70041dcc..e75220af2c 100644
--- a/src/main/java/net/minecraft/server/PortalTravelAgent.java
+++ b/src/main/java/net/minecraft/server/PortalTravelAgent.java
@@ -66,7 +66,7 @@ public class PortalTravelAgent {
             for (int k1 = i1 - short1; k1 <= i1 + short1; ++k1) {
                 double d3 = (double) k1 + 0.5D - entity.locZ;
 
-                for (int l1 = world.height - 1; l1 >= 0; --l1) {
+                for (int l1 = 127; l1 >= 0; --l1) {
                     if (world.getTypeId(j1, l1, k1) == Block.PORTAL.id) {
                         while (world.getTypeId(j1, l1 - 1, k1) == Block.PORTAL.id) {
                             --l1;
@@ -150,7 +150,7 @@ public class PortalTravelAgent {
                 d2 = (double) j2 + 0.5D - entity.locZ;
 
                 label274:
-                for (l2 = world.height - 1; l2 >= 0; --l2) {
+                for (l2 = 127; l2 >= 0; --l2) {
                     if (world.isEmpty(i2, l2, j2)) {
                         while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) {
                             --l2;
@@ -201,7 +201,7 @@ public class PortalTravelAgent {
                     d2 = (double) j2 + 0.5D - entity.locZ;
 
                     label222:
-                    for (l2 = world.height - 1; l2 >= 0; --l2) {
+                    for (l2 = 127; l2 >= 0; --l2) {
                         if (world.isEmpty(i2, l2, j2)) {
                             while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) {
                                 --l2;
@@ -257,8 +257,8 @@ public class PortalTravelAgent {
                 i1 = 70;
             }
 
-            if (i1 > world.height - 10) {
-                i1 = world.height - 10;
+            if (i1 > 118) {
+                i1 = 118;
             }
 
             j5 = i1;
diff --git a/src/main/java/net/minecraft/server/ServerConfigurationManager.java b/src/main/java/net/minecraft/server/ServerConfigurationManager.java
index c5399f1416..33b59bdcd6 100644
--- a/src/main/java/net/minecraft/server/ServerConfigurationManager.java
+++ b/src/main/java/net/minecraft/server/ServerConfigurationManager.java
@@ -303,7 +303,7 @@ public class ServerConfigurationManager {
 
         // CraftBukkit start
         byte actualDimension = (byte) (worldserver.getWorld().getEnvironment().getId());
-        entityplayer1.netServerHandler.sendPacket(new Packet9Respawn(actualDimension, (byte) worldserver.difficulty, worldserver.getSeed(), worldserver.getWorldData().getType(), worldserver.height, entityplayer.itemInWorldManager.getGameMode()));
+        entityplayer1.netServerHandler.sendPacket(new Packet9Respawn(actualDimension, (byte) worldserver.difficulty, worldserver.getWorldData().getType(), worldserver.getHeight(), entityplayer.itemInWorldManager.getGameMode()));
         entityplayer1.spawnIn(worldserver);
         entityplayer1.dead = false;
         entityplayer1.netServerHandler.teleport(new Location(worldserver.getWorld(), entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch));
@@ -313,7 +313,7 @@ public class ServerConfigurationManager {
         worldserver.addEntity(entityplayer1);
         this.players.add(entityplayer1);
         this.updateClient(entityplayer1); // CraftBukkit
-        entityplayer1.B();
+        entityplayer1.E();
         // CraftBukkit start - don't fire on respawn
         if (fromWorld != location.getWorld()) {
             org.bukkit.event.player.PlayerChangedWorldEvent event = new org.bukkit.event.player.PlayerChangedWorldEvent((Player) entityplayer1.getBukkitEntity(), fromWorld);
@@ -741,14 +741,14 @@ public class ServerConfigurationManager {
 
     public void a(EntityPlayer entityplayer, WorldServer worldserver) {
         entityplayer.netServerHandler.sendPacket(new Packet4UpdateTime(worldserver.getTime()));
-        if (worldserver.w()) {
+        if (worldserver.x()) {
             entityplayer.netServerHandler.sendPacket(new Packet70Bed(1, 0));
         }
     }
 
     public void updateClient(EntityPlayer entityplayer) {
         entityplayer.updateInventory(entityplayer.defaultContainer);
-        entityplayer.t_();
+        entityplayer.J();
         entityplayer.lastSentExp = -1; // CraftBukkit
     }
 
diff --git a/src/main/java/net/minecraft/server/Slot.java b/src/main/java/net/minecraft/server/Slot.java
index ee8f12ac95..649a349d19 100644
--- a/src/main/java/net/minecraft/server/Slot.java
+++ b/src/main/java/net/minecraft/server/Slot.java
@@ -15,7 +15,23 @@ public class Slot {
         this.e = k;
     }
 
-    public void b(ItemStack itemstack) {
+    public void a(ItemStack itemstack, ItemStack itemstack1) {
+        if (itemstack != null && itemstack1 != null) {
+            if (itemstack.id == itemstack1.id) {
+                int i = itemstack1.count - itemstack.count;
+
+                if (i > 0) {
+                    this.a(itemstack, i);
+                }
+            }
+        }
+    }
+
+    protected void a(ItemStack itemstack, int i) {}
+
+    protected void b(ItemStack itemstack) {}
+
+    public void c(ItemStack itemstack) {
         this.d();
     }
 
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index be92404f6f..09806d7aba 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -40,9 +40,10 @@ public final class SpawnerCreature {
     public SpawnerCreature() {}
 
     protected static ChunkPosition getRandomPosition(World world, int i, int j) {
-        int k = i + world.random.nextInt(16);
-        int l = world.random.nextInt(world.height);
-        int i1 = j + world.random.nextInt(16);
+        Chunk chunk = world.getChunkAt(i, j);
+        int k = i * 16 + world.random.nextInt(16);
+        int l = world.random.nextInt(chunk == null ? 128 : Math.max(128, chunk.g()));
+        int i1 = j * 16 + world.random.nextInt(16);
 
         return new ChunkPosition(k, l, i1);
     }
@@ -157,7 +158,7 @@ public final class SpawnerCreature {
                                                                 // CraftBukkit - added a reason for spawning this creature
                                                                 world.addEntity(entityliving, SpawnReason.NATURAL);
                                                                 a(entityliving, world, f, f1, f2);
-                                                                if (j2 >= entityliving.p()) {
+                                                                if (j2 >= entityliving.q()) {
                                                                     continue label108;
                                                                 }
                                                             }
@@ -186,8 +187,14 @@ public final class SpawnerCreature {
         }
     }
 
-    private static boolean a(EnumCreatureType enumcreaturetype, World world, int i, int j, int k) {
-        return enumcreaturetype.c() == Material.WATER ? world.getMaterial(i, j, k).isLiquid() && !world.e(i, j + 1, k) : world.e(i, j - 1, k) && !world.e(i, j, k) && !world.getMaterial(i, j, k).isLiquid() && !world.e(i, j + 1, k);
+    public static boolean a(EnumCreatureType enumcreaturetype, World world, int i, int j, int k) {
+        if (enumcreaturetype.c() == Material.WATER) {
+            return world.getMaterial(i, j, k).isLiquid() && !world.e(i, j + 1, k);
+        } else {
+            int l = world.getTypeId(i, j - 1, k);
+
+            return Block.g(l) && l != Block.BEDROCK.id && !world.e(i, j, k) && !world.getMaterial(i, j, k).isLiquid() && !world.e(i, j + 1, k);
+        }
     }
 
     private static void a(EntityLiving entityliving, World world, float f, float f1, float f2) {
@@ -200,6 +207,14 @@ public final class SpawnerCreature {
             entityskeleton.mount(entityliving);
         } else if (entityliving instanceof EntitySheep) {
             ((EntitySheep) entityliving).setColor(EntitySheep.a(world.random));
+        } else if (entityliving instanceof EntityOcelot && world.random.nextInt(7) == 0) {
+            for (int i = 0; i < 2; ++i) {
+                EntityOcelot entityocelot = new EntityOcelot(world);
+
+                entityocelot.setPositionRotation((double) f, (double) f1, (double) f2, entityliving.yaw, 0.0F);
+                entityocelot.setAge(-24000);
+                world.addEntity(entityocelot);
+            }
         }
     }
 
@@ -207,7 +222,7 @@ public final class SpawnerCreature {
         List list = biomebase.getMobs(EnumCreatureType.CREATURE);
 
         if (!list.isEmpty()) {
-            while (random.nextFloat() < biomebase.d()) {
+            while (random.nextFloat() < biomebase.e()) {
                 BiomeMeta biomemeta = (BiomeMeta) WeightedRandom.a(world.random, (Collection) list);
                 int i1 = biomemeta.b + random.nextInt(1 + biomemeta.c - biomemeta.b);
                 int j1 = i + random.nextInt(k);
@@ -219,7 +234,7 @@ public final class SpawnerCreature {
                     boolean flag = false;
 
                     for (int k2 = 0; !flag && k2 < 4; ++k2) {
-                        int l2 = world.f(j1, k1);
+                        int l2 = world.g(j1, k1);
 
                         if (a(EnumCreatureType.CREATURE, world, j1, l2, k1)) {
                             float f = (float) j1 + 0.5F;
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index 18095d2a4a..8137c78ef8 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -50,7 +50,7 @@ public class TileEntity {
         }
     }
 
-    public void l_() {}
+    public void q_() {}
 
     public static TileEntity c(NBTTagCompound nbttagcompound) {
         TileEntity tileentity = null;
@@ -74,7 +74,7 @@ public class TileEntity {
         return tileentity;
     }
 
-    public int j() {
+    public int k() {
         if (this.p == -1) {
             this.p = this.world.getData(this.x, this.y, this.z);
         }
@@ -89,7 +89,7 @@ public class TileEntity {
         }
     }
 
-    public Packet k() {
+    public Packet d() {
         return null;
     }
 
@@ -97,7 +97,7 @@ public class TileEntity {
         return this.o;
     }
 
-    public void i() {
+    public void j() {
         this.o = true;
     }
 
@@ -107,7 +107,7 @@ public class TileEntity {
 
     public void b(int i, int j) {}
 
-    public void d() {
+    public void h() {
         this.q = null;
         this.p = -1;
     }
diff --git a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java
index 398dff92c5..0c50bb6ba8 100644
--- a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java
+++ b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java
@@ -42,14 +42,14 @@ public class TileEntityBrewingStand extends TileEntity implements IInventory {
     // CraftBukkit end
 
     public String getName() {
-        return "Brewing Stand";
+        return "container.brewing";
     }
 
     public int getSize() {
         return this.items.length;
     }
 
-    public void l_() {
+    public void q_() {
         if (this.brewTime > 0) {
             --this.brewTime;
             if (this.brewTime == 0) {
@@ -74,10 +74,10 @@ public class TileEntityBrewingStand extends TileEntity implements IInventory {
             this.world.setData(this.x, this.y, this.z, i);
         }
 
-        super.l_();
+        super.q_();
     }
 
-    public int h() {
+    public int i() {
         return this.brewTime;
     }
 
@@ -210,6 +210,17 @@ public class TileEntityBrewingStand extends TileEntity implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        if (i >= 0 && i < this.items.length) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         if (i >= 0 && i < this.items.length) {
             this.items[i] = itemstack;
diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java
index af17130430..ce2ad48989 100644
--- a/src/main/java/net/minecraft/server/TileEntityChest.java
+++ b/src/main/java/net/minecraft/server/TileEntityChest.java
@@ -74,6 +74,17 @@ public class TileEntityChest extends TileEntity implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         this.items[i] = itemstack;
         if (itemstack != null && itemstack.count > this.getMaxStackSize()) {
@@ -84,7 +95,7 @@ public class TileEntityChest extends TileEntity implements IInventory {
     }
 
     public String getName() {
-        return "Chest";
+        return "container.chest";
     }
 
     public void a(NBTTagCompound nbttagcompound) {
@@ -129,12 +140,12 @@ public class TileEntityChest extends TileEntity implements IInventory {
         return this.world.getTileEntity(this.x, this.y, this.z) != this ? false : entityhuman.e((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D) <= 64.0D;
     }
 
-    public void d() {
-        super.d();
+    public void h() {
+        super.h();
         this.a = false;
     }
 
-    public void h() {
+    public void i() {
         if (!this.a) {
             this.a = true;
             this.b = null;
@@ -158,19 +169,19 @@ public class TileEntityChest extends TileEntity implements IInventory {
             }
 
             if (this.b != null) {
-                this.b.d();
+                this.b.h();
             }
 
             if (this.e != null) {
-                this.e.d();
+                this.e.h();
             }
 
             if (this.c != null) {
-                this.c.d();
+                this.c.h();
             }
 
             if (this.d != null) {
-                this.d.d();
+                this.d.h();
             }
         }
     }
@@ -193,10 +204,10 @@ public class TileEntityChest extends TileEntity implements IInventory {
     }
     // CraftBukkit end
 
-    public void l_() {
-        super.l_();
+    public void q_() {
+        super.q_();
         if (this.world == null) return; // CraftBukkit
-        this.h();
+        this.i();
         if (++this.ticks % (20 * 4) == 0) { // CraftBukkit
             this.world.playNote(this.x, this.y, this.z, 1, this.h);
         }
@@ -274,9 +285,9 @@ public class TileEntityChest extends TileEntity implements IInventory {
         this.world.playNote(this.x, this.y, this.z, 1, this.h);
     }
 
-    public void i() {
-        this.d();
+    public void j() {
         this.h();
-        super.i();
+        this.i();
+        super.j();
     }
 }
diff --git a/src/main/java/net/minecraft/server/TileEntityDispenser.java b/src/main/java/net/minecraft/server/TileEntityDispenser.java
index 3ea803c842..553a3b2e31 100644
--- a/src/main/java/net/minecraft/server/TileEntityDispenser.java
+++ b/src/main/java/net/minecraft/server/TileEntityDispenser.java
@@ -68,7 +68,18 @@ public class TileEntityDispenser extends TileEntity implements IInventory {
         }
     }
 
-    // CraftBukkit - change signature
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
+    // CraftBukkit start - move code out from p_
     public int findDispenseSlot() {
         int i = -1;
         int j = 1;
@@ -79,12 +90,10 @@ public class TileEntityDispenser extends TileEntity implements IInventory {
                 i = k;
             }
         }
-
-        // CraftBukkit start
         return i;
     }
 
-    public ItemStack k_() {
+    public ItemStack p_() {
         int i = this.findDispenseSlot();
         // CraftBukkit end
 
@@ -105,7 +114,7 @@ public class TileEntityDispenser extends TileEntity implements IInventory {
     }
 
     public String getName() {
-        return "Trap";
+        return "container.dispenser";
     }
 
     public void a(NBTTagCompound nbttagcompound) {
diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java
index 13c98ee6ff..9790ea5084 100644
--- a/src/main/java/net/minecraft/server/TileEntityFurnace.java
+++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java
@@ -72,6 +72,17 @@ public class TileEntityFurnace extends TileEntity implements IInventory {
         }
     }
 
+    public ItemStack splitWithoutUpdate(int i) {
+        if (this.items[i] != null) {
+            ItemStack itemstack = this.items[i];
+
+            this.items[i] = null;
+            return itemstack;
+        } else {
+            return null;
+        }
+    }
+
     public void setItem(int i, ItemStack itemstack) {
         this.items[i] = itemstack;
         if (itemstack != null && itemstack.count > this.getMaxStackSize()) {
@@ -80,7 +91,7 @@ public class TileEntityFurnace extends TileEntity implements IInventory {
     }
 
     public String getName() {
-        return "Furnace";
+        return "container.furnace";
     }
 
     public void a(NBTTagCompound nbttagcompound) {
@@ -130,7 +141,7 @@ public class TileEntityFurnace extends TileEntity implements IInventory {
         return this.burnTime > 0;
     }
 
-    public void l_() {
+    public void q_() {
         boolean flag = this.burnTime > 0;
         boolean flag1 = false;
 
diff --git a/src/main/java/net/minecraft/server/TileEntityMobSpawner.java b/src/main/java/net/minecraft/server/TileEntityMobSpawner.java
index 2f360878cf..c50727b8dc 100644
--- a/src/main/java/net/minecraft/server/TileEntityMobSpawner.java
+++ b/src/main/java/net/minecraft/server/TileEntityMobSpawner.java
@@ -21,7 +21,7 @@ public class TileEntityMobSpawner extends TileEntity {
         return this.world.findNearbyPlayer((double) this.x + 0.5D, (double) this.y + 0.5D, (double) this.z + 0.5D, 16.0D) != null;
     }
 
-    public void l_() {
+    public void q_() {
         this.c = this.b;
         if (this.c()) {
             double d0 = (double) ((float) this.x + this.world.random.nextFloat());
@@ -79,14 +79,14 @@ public class TileEntityMobSpawner extends TileEntity {
                         if (entityliving.canSpawn()) {
                             this.world.addEntity(entityliving, SpawnReason.SPAWNER); // CraftBukkit
                             this.world.triggerEffect(2004, this.x, this.y, this.z, 0);
-                            entityliving.ao();
+                            entityliving.aB();
                             this.e();
                         }
                     }
                 }
             }
 
-            super.l_();
+            super.q_();
         }
     }
 
@@ -105,4 +105,10 @@ public class TileEntityMobSpawner extends TileEntity {
         nbttagcompound.setString("EntityId", this.mobName);
         nbttagcompound.setShort("Delay", (short) this.spawnDelay);
     }
+
+    public Packet d() {
+        int i = EntityTypes.a(this.mobName);
+
+        return new Packet132TileEntityData(this.x, this.y, this.z, 1, i);
+    }
 }
diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java
index ffc3286bd7..b0e0465b7b 100644
--- a/src/main/java/net/minecraft/server/TileEntityPiston.java
+++ b/src/main/java/net/minecraft/server/TileEntityPiston.java
@@ -29,7 +29,7 @@ public class TileEntityPiston extends TileEntity {
         return this.a;
     }
 
-    public int j() {
+    public int k() {
         return this.b;
     }
 
@@ -59,7 +59,7 @@ public class TileEntityPiston extends TileEntity {
         AxisAlignedBB axisalignedbb = Block.PISTON_MOVING.b(this.world, this.x, this.y, this.z, this.a, f, this.c);
 
         if (axisalignedbb != null) {
-            List list = this.world.getEntities(null, axisalignedbb);
+            List list = this.world.getEntities((Entity) null, axisalignedbb);
 
             if (!list.isEmpty()) {
                 h.addAll(list);
@@ -79,22 +79,22 @@ public class TileEntityPiston extends TileEntity {
     public void g() {
         if (this.g < 1.0F && this.world != null) {
             this.g = this.f = 1.0F;
-            this.world.n(this.x, this.y, this.z);
-            this.i();
+            this.world.q(this.x, this.y, this.z);
+            this.j();
             if (this.world.getTypeId(this.x, this.y, this.z) == Block.PISTON_MOVING.id) {
                 this.world.setTypeIdAndData(this.x, this.y, this.z, this.a, this.b);
             }
         }
     }
 
-    public void l_() {
+    public void q_() {
         if (this.world == null) return; // CraftBukkit
 
         this.g = this.f;
         if (this.g >= 1.0F) {
             this.a(1.0F, 0.25F);
-            this.world.n(this.x, this.y, this.z);
-            this.i();
+            this.world.q(this.x, this.y, this.z);
+            this.j();
             if (this.world.getTypeId(this.x, this.y, this.z) == Block.PISTON_MOVING.id) {
                 this.world.setTypeIdAndData(this.x, this.y, this.z, this.a, this.b);
             }
diff --git a/src/main/java/net/minecraft/server/TileEntitySign.java b/src/main/java/net/minecraft/server/TileEntitySign.java
index ac62335f87..2b0d4a11b4 100644
--- a/src/main/java/net/minecraft/server/TileEntitySign.java
+++ b/src/main/java/net/minecraft/server/TileEntitySign.java
@@ -28,7 +28,7 @@ public class TileEntitySign extends TileEntity {
         }
     }
 
-    public Packet k() {
+    public Packet d() {
         String[] astring = new String[4];
 
         for (int i = 0; i < 4; ++i) {
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 5b9c1a44b2..e9ac624662 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -33,57 +33,66 @@ import org.bukkit.block.BlockState;
 
 public class World implements IBlockAccess {
 
-    public int heightBits = 7;
-    public int heightBitsPlusFour;
-    public int height;
-    public int heightMinusOne;
-    public int seaLevel;
-    public boolean f;
-    public List entityList;
-    private List J;
-    private TreeSet K;
-    private Set L;
-    public List tileEntityList;
-    private List M;
-    private List N;
-    public List players;
-    public List j;
-    private long O;
-    public int k;
-    protected int l;
-    protected final int m;
-    protected float n;
-    protected float o;
-    protected float p;
-    protected float q;
-    protected int r;
-    public int s;
-    public boolean suppressPhysics;
-    private long P;
-    protected int u;
+    public boolean a = false;
+    public List entityList = new ArrayList();
+    private List G = new ArrayList();
+    private TreeSet H = new TreeSet();
+    private Set I = new HashSet();
+    public List tileEntityList = new ArrayList();
+    private List J = new ArrayList();
+    private List K = new ArrayList();
+    public List players = new ArrayList();
+    public List e = new ArrayList();
+    private long L = 16777215L;
+    public int f = 0;
+    protected int g = (new Random()).nextInt();
+    protected final int h = 1013904223;
+    protected float i;
+    protected float j;
+    protected float k;
+    protected float l;
+    protected int m = 0;
+    public int n = 0;
+    public boolean suppressPhysics = false;
+    private long M = System.currentTimeMillis();
+    protected int p = 40;
     public int difficulty;
-    public Random random;
-    public boolean x;
+    public Random random = new Random();
+    public boolean s = false;
     public WorldProvider worldProvider; // CraftBukkit - remove final
-    protected List z;
+    protected List u = new ArrayList();
     public IChunkProvider chunkProvider; // CraftBukkit - protected -> public
     protected final IDataManager dataManager;
     public WorldData worldData; // CraftBukkit - protected -> public
     public boolean isLoading;
-    private boolean Q;
+    private boolean N;
     public WorldMapCollection worldMaps;
-    private ArrayList R;
-    private boolean S;
-    public boolean allowMonsters; // CraftBukkit - private -> public
-    public boolean allowAnimals; // CraftBukkit - private -> public
+    public final VillageCollection villages = new VillageCollection(this);
+    private final VillageSiege O = new VillageSiege(this);
+    private ArrayList P = new ArrayList();
+    private boolean Q;
+    public boolean allowMonsters = true; // CraftBukkit - private -> public
+    public boolean allowAnimals = true; // CraftBukkit - private -> public
     private LongHashset chunkTickList; // CraftBukkit
     public long ticksPerAnimalSpawns; // CraftBukkit
     public long ticksPerMonsterSpawns; // CraftBukkit
-    private int U;
-    int[] H;
-    private List V;
+    private int R;
+    int[] E;
+    private List S;
     public boolean isStatic;
 
+    public BiomeBase getBiome(int i, int j) {
+        if (this.isLoaded(i, 0, j)) {
+            Chunk chunk = this.getChunkAtWorldCoords(i, j);
+
+            if (chunk != null) {
+                return chunk.a(i & 15, j & 15, this.worldProvider.c);
+            }
+        }
+
+        return this.worldProvider.c.getBiome(i, j);
+    }
+
     public WorldChunkManager getWorldChunkManager() {
         return this.worldProvider.c;
     }
@@ -120,50 +129,21 @@ public class World implements IBlockAccess {
         this.world = new CraftWorld((WorldServer) this, gen, env);
         // CraftBukkit end
 
-        this.heightBitsPlusFour = this.heightBits + 4;
-        this.height = 1 << this.heightBits;
-        this.heightMinusOne = this.height - 1;
-        this.seaLevel = this.height / 2 - 1;
-        this.f = false;
-        this.entityList = new ArrayList();
-        this.J = new ArrayList();
-        this.K = new TreeSet();
-        this.L = new HashSet();
-        this.tileEntityList = new ArrayList();
-        this.M = new ArrayList();
-        this.N = new ArrayList();
-        this.players = new ArrayList();
-        this.j = new ArrayList();
-        this.O = 16777215L;
-        this.k = 0;
-        this.l = (new Random()).nextInt();
-        this.m = 1013904223;
-        this.r = 0;
-        this.s = 0;
-        this.suppressPhysics = false;
-        this.P = System.currentTimeMillis();
-        this.u = 40;
-        this.random = new Random();
-        this.x = false;
-        this.z = new ArrayList();
-        this.R = new ArrayList();
-        this.allowMonsters = true;
-        this.allowAnimals = true;
         this.chunkTickList = new LongHashset(); // CraftBukkit
         this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
         this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit
-        this.U = this.random.nextInt(12000);
-        this.H = new int['\u8000'];
-        this.V = new ArrayList();
+        this.R = this.random.nextInt(12000);
+        this.E = new int['\u8000'];
+        this.S = new ArrayList();
         this.isStatic = false;
         this.dataManager = idatamanager;
         this.worldMaps = new WorldMapCollection(idatamanager);
         this.worldData = idatamanager.getWorldData();
-        this.x = this.worldData == null;
+        this.s = this.worldData == null;
         if (worldprovider != null) {
             this.worldProvider = worldprovider;
-        } else if (this.worldData != null && this.worldData.h() != 0) {
-            this.worldProvider = WorldProvider.byDimension(this.worldData.h());
+        } else if (this.worldData != null && this.worldData.g() != 0) {
+            this.worldProvider = WorldProvider.byDimension(this.worldData.g());
         } else {
             this.worldProvider = WorldProvider.byDimension(0);
         }
@@ -184,7 +164,7 @@ public class World implements IBlockAccess {
         }
 
         this.g();
-        this.z();
+        this.B();
 
         this.getServer().addWorld(this.world); // CraftBukkit
     }
@@ -200,7 +180,7 @@ public class World implements IBlockAccess {
             this.worldData.setSpawn(0, this.worldProvider.getSeaLevel(), 0);
         } else {
             this.isLoading = true;
-            WorldChunkManager worldchunkmanager = this.getWorldChunkManager();
+            WorldChunkManager worldchunkmanager = this.worldProvider.c;
             List list = worldchunkmanager.a();
             Random random = new Random(this.getSeed());
             ChunkPosition chunkposition = worldchunkmanager.a(0, 0, 256, list, random);
@@ -234,7 +214,7 @@ public class World implements IBlockAccess {
 
             int l = 0;
 
-            // CraftBukkit - use out own canSpawn
+            // CraftBukkit - use our own canSpawn
             while (!this.canSpawn(i, k)) {
                 i += random.nextInt(64) - random.nextInt(64);
                 k += random.nextInt(64) - random.nextInt(64);
@@ -250,13 +230,13 @@ public class World implements IBlockAccess {
     }
 
     public ChunkCoordinates getDimensionSpawn() {
-        return this.worldProvider.d();
+        return this.worldProvider.e();
     }
 
-    public int a(int i, int j) {
+    public int b(int i, int j) {
         int k;
 
-        for (k = this.seaLevel; !this.isEmpty(i, k + 1, j); ++k) {
+        for (k = 63; !this.isEmpty(i, k + 1, j); ++k) {
             ;
         }
 
@@ -269,7 +249,7 @@ public class World implements IBlockAccess {
                 iprogressupdate.a("Saving level");
             }
 
-            this.y();
+            this.A();
             if (iprogressupdate != null) {
                 iprogressupdate.b("Saving chunks");
             }
@@ -278,22 +258,32 @@ public class World implements IBlockAccess {
         }
     }
 
-    private void y() {
-        this.l();
+    private void A() {
+        this.m();
         this.dataManager.saveWorldData(this.worldData, this.players);
         this.worldMaps.a();
     }
 
     public int getTypeId(int i, int j, int k) {
-        return i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000 ? (j < 0 ? 0 : (j >= this.height ? 0 : this.getChunkAt(i >> 4, k >> 4).getTypeId(i & 15, j, k & 15))) : 0;
+        return i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000 ? (j < 0 ? 0 : (j >= 256 ? 0 : this.getChunkAt(i >> 4, k >> 4).getTypeId(i & 15, j, k & 15))) : 0;
+    }
+
+    public int f(int i, int j, int k) {
+        return i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000 ? (j < 0 ? 0 : (j >= 256 ? 0 : this.getChunkAt(i >> 4, k >> 4).b(i & 15, j, k & 15))) : 0;
     }
 
     public boolean isEmpty(int i, int j, int k) {
         return this.getTypeId(i, j, k) == 0;
     }
 
+    public boolean isTileEntity(int i, int j, int k) {
+        int l = this.getTypeId(i, j, k);
+
+        return Block.byId[l] != null && Block.byId[l].n();
+    }
+
     public boolean isLoaded(int i, int j, int k) {
-        return j >= 0 && j < this.height ? this.isChunkLoaded(i >> 4, k >> 4) : false;
+        return j >= 0 && j < 256 ? this.isChunkLoaded(i >> 4, k >> 4) : false;
     }
 
     public boolean areChunksLoaded(int i, int j, int k, int l) {
@@ -301,12 +291,10 @@ public class World implements IBlockAccess {
     }
 
     public boolean a(int i, int j, int k, int l, int i1, int j1) {
-        if (i1 >= 0 && j < this.height) {
+        if (i1 >= 0 && j < 256) {
             i >>= 4;
-            j >>= 4;
             k >>= 4;
             l >>= 4;
-            i1 >>= 4;
             j1 >>= 4;
 
             for (int k1 = i; k1 <= l; ++k1) {
@@ -350,13 +338,15 @@ public class World implements IBlockAccess {
         if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
             if (j < 0) {
                 return false;
-            } else if (j >= this.height) {
+            } else if (j >= 256) {
                 return false;
             } else {
                 Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
                 boolean flag = chunk.a(i & 15, j, k & 15, l, i1);
 
-                this.s(i, j, k);
+                // MethodProfiler.a("checkLight"); // CraftBukkit - not in production code
+                this.v(i, j, k);
+                // MethodProfiler.a(); // CraftBukkit - not in production code
                 return flag;
             }
         } else {
@@ -368,13 +358,15 @@ public class World implements IBlockAccess {
         if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
             if (j < 0) {
                 return false;
-            } else if (j >= this.height) {
+            } else if (j >= 256) {
                 return false;
             } else {
                 Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
                 boolean flag = chunk.a(i & 15, j, k & 15, l);
 
-                this.s(i, j, k);
+                // MethodProfiler.a("checkLight"); // CraftBukkit - not in production code
+                this.v(i, j, k);
+                // MethodProfiler.a(); // CraftBukkit - not in production code
                 return flag;
             }
         } else {
@@ -392,7 +384,7 @@ public class World implements IBlockAccess {
         if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
             if (j < 0) {
                 return 0;
-            } else if (j >= this.height) {
+            } else if (j >= 256) {
                 return 0;
             } else {
                 Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
@@ -410,7 +402,7 @@ public class World implements IBlockAccess {
         if (this.setRawData(i, j, k, l)) {
             int i1 = this.getTypeId(i, j, k);
 
-            if (Block.t[i1 & 255]) {
+            if (Block.r[i1 & 4095]) {
                 this.update(i, j, k, i1);
             } else {
                 this.applyPhysics(i, j, k, i1);
@@ -422,7 +414,7 @@ public class World implements IBlockAccess {
         if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
             if (j < 0) {
                 return false;
-            } else if (j >= this.height) {
+            } else if (j >= 256) {
                 return false;
             } else {
                 Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
@@ -461,12 +453,12 @@ public class World implements IBlockAccess {
     }
 
     public void notify(int i, int j, int k) {
-        for (int l = 0; l < this.z.size(); ++l) {
-            ((IWorldAccess) this.z.get(l)).a(i, j, k);
+        for (int l = 0; l < this.u.size(); ++l) {
+            ((IWorldAccess) this.u.get(l)).a(i, j, k);
         }
     }
 
-    protected void update(int i, int j, int k, int l) {
+    public void update(int i, int j, int k, int l) {
         this.notify(i, j, k);
         this.applyPhysics(i, j, k, l);
     }
@@ -480,7 +472,7 @@ public class World implements IBlockAccess {
             k = i1;
         }
 
-        if (!this.worldProvider.f) {
+        if (!this.worldProvider.e) {
             for (i1 = k; i1 <= l; ++i1) {
                 this.b(EnumSkyBlock.SKY, i, i1, j);
             }
@@ -489,15 +481,15 @@ public class World implements IBlockAccess {
         this.b(i, k, j, i, l, j);
     }
 
-    public void i(int i, int j, int k) {
-        for (int l = 0; l < this.z.size(); ++l) {
-            ((IWorldAccess) this.z.get(l)).a(i, j, k, i, j, k);
+    public void k(int i, int j, int k) {
+        for (int l = 0; l < this.u.size(); ++l) {
+            ((IWorldAccess) this.u.get(l)).a(i, j, k, i, j, k);
         }
     }
 
     public void b(int i, int j, int k, int l, int i1, int j1) {
-        for (int k1 = 0; k1 < this.z.size(); ++k1) {
-            ((IWorldAccess) this.z.get(k1)).a(i, j, k, l, i1, j1);
+        for (int k1 = 0; k1 < this.u.size(); ++k1) {
+            ((IWorldAccess) this.u.get(k1)).a(i, j, k, l, i1, j1);
         }
     }
 
@@ -533,15 +525,15 @@ public class World implements IBlockAccess {
     }
 
     public boolean isChunkLoaded(int i, int j, int k) {
-        return this.getChunkAt(i >> 4, k >> 4).c(i & 15, j, k & 15);
+        return this.getChunkAt(i >> 4, k >> 4).d(i & 15, j, k & 15);
     }
 
-    public int k(int i, int j, int k) {
+    public int m(int i, int j, int k) {
         if (j < 0) {
             return 0;
         } else {
-            if (j >= this.height) {
-                j = this.height - 1;
+            if (j >= 256) {
+                j = 255;
             }
 
             return this.getChunkAt(i >> 4, k >> 4).c(i & 15, j, k & 15, 0);
@@ -587,15 +579,15 @@ public class World implements IBlockAccess {
             if (j < 0) {
                 return 0;
             } else {
-                if (j >= this.height) {
-                    j = this.height - 1;
+                if (j >= 256) {
+                    j = 255;
                 }
 
                 Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
 
                 i &= 15;
                 k &= 15;
-                return chunk.c(i, j, k, this.k);
+                return chunk.c(i, j, k, this.f);
             }
         } else {
             return 15;
@@ -621,16 +613,16 @@ public class World implements IBlockAccess {
             j = 0;
         }
 
-        if (j >= this.height) {
-            j = this.height - 1;
+        if (j >= 256) {
+            j = 255;
         }
 
-        if (j >= 0 && j < this.height && i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
+        if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
             int l = i >> 4;
             int i1 = k >> 4;
 
             if (!this.isChunkLoaded(l, i1)) {
-                return 0;
+                return enumskyblock.c;
             } else {
                 Chunk chunk = this.getChunkAt(l, i1);
 
@@ -644,14 +636,14 @@ public class World implements IBlockAccess {
     public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) {
         if (i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000) {
             if (j >= 0) {
-                if (j < this.height) {
+                if (j < 256) {
                     if (this.isChunkLoaded(i >> 4, k >> 4)) {
                         Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
 
                         chunk.a(enumskyblock, i & 15, j, k & 15, l);
 
-                        for (int i1 = 0; i1 < this.z.size(); ++i1) {
-                            ((IWorldAccess) this.z.get(i1)).a(i, j, k);
+                        for (int i1 = 0; i1 < this.u.size(); ++i1) {
+                            ((IWorldAccess) this.u.get(i1)).b(i, j, k);
                         }
                     }
                 }
@@ -659,12 +651,18 @@ public class World implements IBlockAccess {
         }
     }
 
-    public float m(int i, int j, int k) {
-        return this.worldProvider.g[this.getLightLevel(i, j, k)];
+    public void o(int i, int j, int k) {
+        for (int l = 0; l < this.u.size(); ++l) {
+            ((IWorldAccess) this.u.get(l)).b(i, j, k);
+        }
+    }
+
+    public float p(int i, int j, int k) {
+        return this.worldProvider.f[this.getLightLevel(i, j, k)];
     }
 
     public boolean e() {
-        return this.k < 4;
+        return this.f < 4;
     }
 
     public MovingObjectPosition a(Vec3D vec3d, Vec3D vec3d1) {
@@ -835,31 +833,31 @@ public class World implements IBlockAccess {
     }
 
     public void makeSound(Entity entity, String s, float f, float f1) {
-        for (int i = 0; i < this.z.size(); ++i) {
-            ((IWorldAccess) this.z.get(i)).a(s, entity.locX, entity.locY - (double) entity.height, entity.locZ, f, f1);
+        for (int i = 0; i < this.u.size(); ++i) {
+            ((IWorldAccess) this.u.get(i)).a(s, entity.locX, entity.locY - (double) entity.height, entity.locZ, f, f1);
         }
     }
 
     public void makeSound(double d0, double d1, double d2, String s, float f, float f1) {
-        for (int i = 0; i < this.z.size(); ++i) {
-            ((IWorldAccess) this.z.get(i)).a(s, d0, d1, d2, f, f1);
+        for (int i = 0; i < this.u.size(); ++i) {
+            ((IWorldAccess) this.u.get(i)).a(s, d0, d1, d2, f, f1);
         }
     }
 
     public void a(String s, int i, int j, int k) {
-        for (int l = 0; l < this.z.size(); ++l) {
-            ((IWorldAccess) this.z.get(l)).a(s, i, j, k);
+        for (int l = 0; l < this.u.size(); ++l) {
+            ((IWorldAccess) this.u.get(l)).a(s, i, j, k);
         }
     }
 
     public void a(String s, double d0, double d1, double d2, double d3, double d4, double d5) {
-        for (int i = 0; i < this.z.size(); ++i) {
-            ((IWorldAccess) this.z.get(i)).a(s, d0, d1, d2, d3, d4, d5);
+        for (int i = 0; i < this.u.size(); ++i) {
+            ((IWorldAccess) this.u.get(i)).a(s, d0, d1, d2, d3, d4, d5);
         }
     }
 
     public boolean strikeLightning(Entity entity) {
-        this.j.add(entity);
+        this.e.add(entity);
         return true;
     }
 
@@ -920,14 +918,14 @@ public class World implements IBlockAccess {
     }
 
     protected void c(Entity entity) {
-        for (int i = 0; i < this.z.size(); ++i) {
-            ((IWorldAccess) this.z.get(i)).a(entity);
+        for (int i = 0; i < this.u.size(); ++i) {
+            ((IWorldAccess) this.u.get(i)).a(entity);
         }
     }
 
     protected void d(Entity entity) {
-        for (int i = 0; i < this.z.size(); ++i) {
-            ((IWorldAccess) this.z.get(i)).b(entity);
+        for (int i = 0; i < this.u.size(); ++i) {
+            ((IWorldAccess) this.u.get(i)).b(entity);
         }
     }
 
@@ -966,11 +964,11 @@ public class World implements IBlockAccess {
     }
 
     public void addIWorldAccess(IWorldAccess iworldaccess) {
-        this.z.add(iworldaccess);
+        this.u.add(iworldaccess);
     }
 
     public List getCubes(Entity entity, AxisAlignedBB axisalignedbb) {
-        this.R.clear();
+        this.P.clear();
         int i = MathHelper.floor(axisalignedbb.a);
         int j = MathHelper.floor(axisalignedbb.d + 1.0D);
         int k = MathHelper.floor(axisalignedbb.b);
@@ -980,12 +978,12 @@ public class World implements IBlockAccess {
 
         for (int k1 = i; k1 < j; ++k1) {
             for (int l1 = i1; l1 < j1; ++l1) {
-                if (this.isLoaded(k1, this.height / 2, l1)) {
+                if (this.isLoaded(k1, 64, l1)) {
                     for (int i2 = k - 1; i2 < l; ++i2) {
                         Block block = Block.byId[this.getTypeId(k1, i2, l1)];
 
                         if (block != null) {
-                            block.a(this, k1, i2, l1, axisalignedbb, this.R);
+                            block.a(this, k1, i2, l1, axisalignedbb, this.P);
                         }
                     }
                 }
@@ -996,19 +994,19 @@ public class World implements IBlockAccess {
         List list = this.getEntities(entity, axisalignedbb.grow(d0, d0, d0));
 
         for (int j2 = 0; j2 < list.size(); ++j2) {
-            AxisAlignedBB axisalignedbb1 = ((Entity) list.get(j2)).h_();
+            AxisAlignedBB axisalignedbb1 = ((Entity) list.get(j2)).h();
 
             if (axisalignedbb1 != null && axisalignedbb1.a(axisalignedbb)) {
-                this.R.add(axisalignedbb1);
+                this.P.add(axisalignedbb1);
             }
 
-            axisalignedbb1 = entity.a_((Entity) list.get(j2));
+            axisalignedbb1 = entity.b_((Entity) list.get(j2));
             if (axisalignedbb1 != null && axisalignedbb1.a(axisalignedbb)) {
-                this.R.add(axisalignedbb1);
+                this.P.add(axisalignedbb1);
             }
         }
 
-        return this.R;
+        return this.P;
     }
 
     public int a(float f) {
@@ -1034,13 +1032,13 @@ public class World implements IBlockAccess {
         return this.worldProvider.a(this.worldData.getTime(), f);
     }
 
-    public int e(int i, int j) {
-        return this.getChunkAtWorldCoords(i, j).c(i & 15, j & 15);
+    public int f(int i, int j) {
+        return this.getChunkAtWorldCoords(i, j).d(i & 15, j & 15);
     }
 
-    public int f(int i, int j) {
+    public int g(int i, int j) {
         Chunk chunk = this.getChunkAtWorldCoords(i, j);
-        int k = this.height - 1;
+        int k = chunk.g() + 16;
 
         i &= 15;
 
@@ -1059,7 +1057,7 @@ public class World implements IBlockAccess {
         NextTickListEntry nextticklistentry = new NextTickListEntry(i, j, k, l);
         byte b0 = 8;
 
-        if (this.f) {
+        if (this.a) {
             if (this.a(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) {
                 int j1 = this.getTypeId(nextticklistentry.a, nextticklistentry.b, nextticklistentry.c);
 
@@ -1073,9 +1071,9 @@ public class World implements IBlockAccess {
                     nextticklistentry.a((long) i1 + this.worldData.getTime());
                 }
 
-                if (!this.L.contains(nextticklistentry)) {
-                    this.L.add(nextticklistentry);
-                    this.K.add(nextticklistentry);
+                if (!this.I.contains(nextticklistentry)) {
+                    this.I.add(nextticklistentry);
+                    this.H.add(nextticklistentry);
                 }
             }
         }
@@ -1088,9 +1086,9 @@ public class World implements IBlockAccess {
             nextticklistentry.a((long) i1 + this.worldData.getTime());
         }
 
-        if (!this.L.contains(nextticklistentry)) {
-            this.L.add(nextticklistentry);
-            this.K.add(nextticklistentry);
+        if (!this.I.contains(nextticklistentry)) {
+            this.I.add(nextticklistentry);
+            this.H.add(nextticklistentry);
         }
     }
 
@@ -1101,27 +1099,27 @@ public class World implements IBlockAccess {
         int i;
         Entity entity;
 
-        for (i = 0; i < this.j.size(); ++i) {
-            entity = (Entity) this.j.get(i);
+        for (i = 0; i < this.e.size(); ++i) {
+            entity = (Entity) this.e.get(i);
             // CraftBukkit start - fixed an NPE
             if (entity == null) {
                 continue;
             }
             // CraftBukkit end
-            entity.y_();
+            entity.G_();
             if (entity.dead) {
-                this.j.remove(i--);
+                this.e.remove(i--);
             }
         }
 
         // MethodProfiler.b("remove"); // CraftBukkit - not in production code
-        this.entityList.removeAll(this.J);
+        this.entityList.removeAll(this.G);
 
         int j;
         int k;
 
-        for (i = 0; i < this.J.size(); ++i) {
-            entity = (Entity) this.J.get(i);
+        for (i = 0; i < this.G.size(); ++i) {
+            entity = (Entity) this.G.get(i);
             j = entity.ca;
             k = entity.cc;
             if (entity.bZ && this.isChunkLoaded(j, k)) {
@@ -1129,11 +1127,11 @@ public class World implements IBlockAccess {
             }
         }
 
-        for (i = 0; i < this.J.size(); ++i) {
-            this.d((Entity) this.J.get(i));
+        for (i = 0; i < this.G.size(); ++i) {
+            this.d((Entity) this.G.get(i));
         }
 
-        this.J.clear();
+        this.G.clear();
         // MethodProfiler.b("regular"); // CraftBukkit - not in production code
 
         for (i = 0; i < this.entityList.size(); ++i) {
@@ -1167,14 +1165,14 @@ public class World implements IBlockAccess {
         }
 
         // MethodProfiler.b("tileEntities"); // CraftBukkit - not in production code
-        this.S = true;
+        this.Q = true;
         Iterator iterator = this.tileEntityList.iterator();
 
         while (iterator.hasNext()) {
             TileEntity tileentity = (TileEntity) iterator.next();
 
             if (!tileentity.l() && tileentity.world != null && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
-                tileentity.l_();
+                tileentity.q_();
             }
 
             if (tileentity.l()) {
@@ -1183,21 +1181,21 @@ public class World implements IBlockAccess {
                     Chunk chunk = this.getChunkAt(tileentity.x >> 4, tileentity.z >> 4);
 
                     if (chunk != null) {
-                        chunk.e(tileentity.x & 15, tileentity.y, tileentity.z & 15);
+                        chunk.f(tileentity.x & 15, tileentity.y, tileentity.z & 15);
                     }
                 }
             }
         }
 
-        this.S = false;
-        if (!this.N.isEmpty()) {
-            this.tileEntityList.removeAll(this.N);
-            this.N.clear();
+        this.Q = false;
+        if (!this.K.isEmpty()) {
+            this.tileEntityList.removeAll(this.K);
+            this.K.clear();
         }
 
         // MethodProfiler.b("pendingTileEntities"); // CraftBukkit - not in production code
-        if (!this.M.isEmpty()) {
-            Iterator iterator1 = this.M.iterator();
+        if (!this.J.isEmpty()) {
+            Iterator iterator1 = this.J.iterator();
 
             while (iterator1.hasNext()) {
                 TileEntity tileentity1 = (TileEntity) iterator1.next();
@@ -1225,7 +1223,7 @@ public class World implements IBlockAccess {
                 }
             }
 
-            this.M.clear();
+            this.J.clear();
         }
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
@@ -1233,8 +1231,8 @@ public class World implements IBlockAccess {
     }
 
     public void a(Collection collection) {
-        if (this.S) {
-            this.M.addAll(collection);
+        if (this.Q) {
+            this.J.addAll(collection);
         } else {
             this.tileEntityList.addAll(collection);
         }
@@ -1249,7 +1247,7 @@ public class World implements IBlockAccess {
         int j = MathHelper.floor(entity.locZ);
         byte b0 = 32;
 
-        if (!flag || this.a(i - b0, 0, j - b0, i + b0, this.height, j + b0)) {
+        if (!flag || this.a(i - b0, 0, j - b0, i + b0, 0, j + b0)) {
             entity.bL = entity.locX;
             entity.bM = entity.locY;
             entity.bN = entity.locZ;
@@ -1257,9 +1255,9 @@ public class World implements IBlockAccess {
             entity.lastPitch = entity.pitch;
             if (flag && entity.bZ) {
                 if (entity.vehicle != null) {
-                    entity.N();
+                    entity.Q();
                 } else {
-                    entity.y_();
+                    entity.G_();
                 }
             }
 
@@ -1560,7 +1558,7 @@ public class World implements IBlockAccess {
         return (float) i / (float) j;
     }
 
-    public void douseFire(EntityHuman entityhuman, int i, int j, int k, int l) {
+    public boolean douseFire(EntityHuman entityhuman, int i, int j, int k, int l) {
         if (l == 0) {
             --j;
         }
@@ -1588,44 +1586,51 @@ public class World implements IBlockAccess {
         if (this.getTypeId(i, j, k) == Block.FIRE.id) {
             this.a(entityhuman, 1004, i, j, k, 0);
             this.setTypeId(i, j, k, 0);
+            return true;
+        } else {
+            return false;
         }
     }
 
     public TileEntity getTileEntity(int i, int j, int k) {
-        Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
-
-        if (chunk == null) {
+        if (j >= 256) {
             return null;
         } else {
-            TileEntity tileentity = chunk.d(i & 15, j, k & 15);
+            Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
 
-            if (tileentity == null) {
-                Iterator iterator = this.M.iterator();
+            if (chunk == null) {
+                return null;
+            } else {
+                TileEntity tileentity = chunk.e(i & 15, j, k & 15);
 
-                while (iterator.hasNext()) {
-                    TileEntity tileentity1 = (TileEntity) iterator.next();
+                if (tileentity == null) {
+                    Iterator iterator = this.J.iterator();
 
-                    if (!tileentity1.l() && tileentity1.x == i && tileentity1.y == j && tileentity1.z == k) {
-                        tileentity = tileentity1;
-                        break;
+                    while (iterator.hasNext()) {
+                        TileEntity tileentity1 = (TileEntity) iterator.next();
+
+                        if (!tileentity1.l() && tileentity1.x == i && tileentity1.y == j && tileentity1.z == k) {
+                            tileentity = tileentity1;
+                            break;
+                        }
                     }
                 }
-            }
 
-            return tileentity;
+                return tileentity;
+            }
         }
     }
 
     public void setTileEntity(int i, int j, int k, TileEntity tileentity) {
         if (tileentity != null && !tileentity.l()) {
-            if (this.S) {
+            if (this.Q) {
                 tileentity.x = i;
                 tileentity.y = j;
                 tileentity.z = k;
-                this.M.add(tileentity);
+                this.J.add(tileentity);
             } else {
                 // CraftBukkit - order matters, moved down
-                // this.h.add(tileentity);
+                // this.tileEntityList.add(tileentity);
                 Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
 
                 if (chunk != null) {
@@ -1636,40 +1641,38 @@ public class World implements IBlockAccess {
         }
     }
 
-    public void n(int i, int j, int k) {
+    public void q(int i, int j, int k) {
         TileEntity tileentity = this.getTileEntity(i, j, k);
 
-        if (tileentity != null && this.S) {
-            tileentity.i();
-            this.M.remove(tileentity);
+        if (tileentity != null && this.Q) {
+            tileentity.j();
+            this.J.remove(tileentity);
         } else {
             if (tileentity != null) {
-                this.M.remove(tileentity);
+                this.J.remove(tileentity);
                 this.tileEntityList.remove(tileentity);
             }
 
             Chunk chunk = this.getChunkAt(i >> 4, k >> 4);
 
             if (chunk != null) {
-                chunk.e(i & 15, j, k & 15);
+                chunk.f(i & 15, j, k & 15);
             }
         }
     }
 
     public void a(TileEntity tileentity) {
-        this.N.add(tileentity);
+        this.K.add(tileentity);
     }
 
-    public boolean o(int i, int j, int k) {
+    public boolean r(int i, int j, int k) {
         Block block = Block.byId[this.getTypeId(i, j, k)];
 
         return block == null ? false : block.a();
     }
 
     public boolean e(int i, int j, int k) {
-        Block block = Block.byId[this.getTypeId(i, j, k)];
-
-        return block == null ? false : block.material.j() && block.b();
+        return Block.g(this.getTypeId(i, j, k));
     }
 
     public boolean b(int i, int j, int k, boolean flag) {
@@ -1691,8 +1694,8 @@ public class World implements IBlockAccess {
     public void g() {
         int i = this.a(1.0F);
 
-        if (i != this.k) {
-            this.k = i;
+        if (i != this.f) {
+            this.f = i;
         }
     }
 
@@ -1706,7 +1709,7 @@ public class World implements IBlockAccess {
             this.difficulty = 3;
         }
 
-        this.getWorldChunkManager().b();
+        this.worldProvider.c.b();
         this.i();
         long i;
 
@@ -1720,7 +1723,7 @@ public class World implements IBlockAccess {
             if (!flag) {
                 i = this.worldData.getTime() + 24000L;
                 this.worldData.a(i - i % 24000L);
-                this.t();
+                this.u();
             }
         }
 
@@ -1735,12 +1738,12 @@ public class World implements IBlockAccess {
         this.chunkProvider.unloadChunks();
         int j = this.a(1.0F);
 
-        if (j != this.k) {
-            this.k = j;
+        if (j != this.f) {
+            this.f = j;
         }
 
         i = this.worldData.getTime() + 1L;
-        if (i % (long) this.u == 0L) {
+        if (i % (long) this.p == 0L) {
             // MethodProfiler.b("save"); // CraftBukkit - not in production code
             this.save(false, (IProgressUpdate) null);
         }
@@ -1749,23 +1752,26 @@ public class World implements IBlockAccess {
         // MethodProfiler.b("tickPending"); // CraftBukkit - not in production code
         this.a(false);
         // MethodProfiler.b("tickTiles"); // CraftBukkit - not in production code
-        this.k();
+        this.l();
+        // MethodProfiler.b("village"); // CraftBukkit - not in production code
+        this.villages.tick();
+        this.O.a();
         // MethodProfiler.a(); // CraftBukkit - not in production code
     }
 
-    private void z() {
+    private void B() {
         if (this.worldData.hasStorm()) {
-            this.o = 1.0F;
+            this.j = 1.0F;
             if (this.worldData.isThundering()) {
-                this.q = 1.0F;
+                this.l = 1.0F;
             }
         }
     }
 
     protected void i() {
-        if (!this.worldProvider.f) {
-            if (this.r > 0) {
-                --this.r;
+        if (!this.worldProvider.e) {
+            if (this.m > 0) {
+                --this.m;
             }
 
             int i = this.worldData.getThunderDuration();
@@ -1813,39 +1819,39 @@ public class World implements IBlockAccess {
                 }
             }
 
-            this.n = this.o;
+            this.i = this.j;
             if (this.worldData.hasStorm()) {
-                this.o = (float) ((double) this.o + 0.01D);
+                this.j = (float) ((double) this.j + 0.01D);
             } else {
-                this.o = (float) ((double) this.o - 0.01D);
+                this.j = (float) ((double) this.j - 0.01D);
             }
 
-            if (this.o < 0.0F) {
-                this.o = 0.0F;
+            if (this.j < 0.0F) {
+                this.j = 0.0F;
             }
 
-            if (this.o > 1.0F) {
-                this.o = 1.0F;
+            if (this.j > 1.0F) {
+                this.j = 1.0F;
             }
 
-            this.p = this.q;
+            this.k = this.l;
             if (this.worldData.isThundering()) {
-                this.q = (float) ((double) this.q + 0.01D);
+                this.l = (float) ((double) this.l + 0.01D);
             } else {
-                this.q = (float) ((double) this.q - 0.01D);
+                this.l = (float) ((double) this.l - 0.01D);
             }
 
-            if (this.q < 0.0F) {
-                this.q = 0.0F;
+            if (this.l < 0.0F) {
+                this.l = 0.0F;
             }
 
-            if (this.q > 1.0F) {
-                this.q = 1.0F;
+            if (this.l > 1.0F) {
+                this.l = 1.0F;
             }
         }
     }
 
-    private void A() {
+    private void C() {
         // CraftBukkit start
         WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), false);
         this.getServer().getPluginManager().callEvent(weather);
@@ -1868,98 +1874,121 @@ public class World implements IBlockAccess {
     }
 
     protected void k() {
-        // this.T.clear(); // CraftBukkit - removed
+        // this.chunkTickList.clear(); // CraftBukkit - removed
         // MethodProfiler.a("buildList"); // CraftBukkit - not in production code
 
         int i;
+        EntityHuman entityhuman;
         int j;
+        int k;
 
         for (i = 0; i < this.players.size(); ++i) {
-            EntityHuman entityhuman = (EntityHuman) this.players.get(i);
-            int k = MathHelper.floor(entityhuman.locX / 16.0D);
-            int l = MathHelper.floor(entityhuman.locZ / 16.0D);
+            entityhuman = (EntityHuman) this.players.get(i);
+            j = MathHelper.floor(entityhuman.locX / 16.0D);
+            k = MathHelper.floor(entityhuman.locZ / 16.0D);
             byte b0 = 7;
 
-            for (j = -b0; j <= b0; ++j) {
+            for (int l = -b0; l <= b0; ++l) {
                 for (int i1 = -b0; i1 <= b0; ++i1) {
                     this.chunkTickList.add(LongHash.toLong(j + k, i1 + l)); // CraftBukkit
                 }
             }
         }
 
-        if (this.U > 0) {
-            --this.U;
+        // MethodProfiler.a(); // CraftBukkit - not in production code
+        if (this.R > 0) {
+            --this.R;
         }
 
-        i = 0;
-        int j1 = 0;
+        // MethodProfiler.a("playerCheckLight"); // CraftBukkit - not in production code
+        if (!this.players.isEmpty()) {
+            i = this.random.nextInt(this.players.size());
+            entityhuman = (EntityHuman) this.players.get(i);
+            j = MathHelper.floor(entityhuman.locX) + this.random.nextInt(11) - 5;
+            k = MathHelper.floor(entityhuman.locY) + this.random.nextInt(11) - 5;
+            int j1 = MathHelper.floor(entityhuman.locZ) + this.random.nextInt(11) - 5;
+
+            this.v(j, k, j1);
+        }
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
-        // Iterator iterator = this.T.iterator(); // CraftBukkit - removed
+    }
+
+    protected void a(int i, int j, Chunk chunk) {
+        // MethodProfiler.b("tickChunk"); // CraftBukkit - not in production code
+        chunk.j();
+        // MethodProfiler.b("moodSound"); // CraftBukkit - not in production code
+        if (this.R == 0) {
+            this.g = this.g * 3 + 1013904223;
+            int k = this.g >> 2;
+            int l = k & 15;
+            int i1 = k >> 8 & 15;
+            int j1 = k >> 16 & 127;
+            int k1 = chunk.getTypeId(l, j1, i1);
+
+            l += i;
+            i1 += j;
+            if (k1 == 0 && this.m(l, j1, i1) <= this.random.nextInt(8) && this.a(EnumSkyBlock.SKY, l, j1, i1) <= 0) {
+                EntityHuman entityhuman = this.findNearbyPlayer((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D, 8.0D);
+
+                if (entityhuman != null && entityhuman.e((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D) > 4.0D) {
+                    this.makeSound((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.random.nextFloat() * 0.2F);
+                    this.R = this.random.nextInt(12000) + 6000;
+                }
+            }
+        }
+
+        // MethodProfiler.b("checkLight"); // CraftBukkit - not in production code
+        chunk.n();
+    }
+
+    protected void l() {
+        this.k();
+        int i = 0;
+        int j = 0;
+        // Iterator iterator = this.chunkTickList.iterator(); // CraftBukkit
 
         // CraftBukkit start
         for (long chunkCoord : this.chunkTickList.popAll()) {
             int chunkX = LongHash.msw(chunkCoord);
             int chunkZ = LongHash.lsw(chunkCoord);
             // ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
-            int k1 = chunkX * 16;
+            int k = chunkX * 16;
+            int l = chunkZ * 16;
 
-            j = chunkZ * 16;
             // MethodProfiler.a("getChunk"); // CraftBukkit - not in production code
             Chunk chunk = this.getChunkAt(chunkX, chunkZ);
             // CraftBukkit end
 
-            // MethodProfiler.b("tickChunk"); // CraftBukkit - not in production code
-            chunk.i();
-            // MethodProfiler.b("moodSound"); // CraftBukkit - not in production code
-            int l1;
-            int i2;
-            int j2;
-            int k2;
-            int l2;
-
-            if (this.U == 0) {
-                this.l = this.l * 3 + 1013904223;
-                l1 = this.l >> 2;
-                i2 = l1 & 15;
-                j2 = l1 >> 8 & 15;
-                k2 = l1 >> 16 & this.heightMinusOne;
-                l2 = chunk.getTypeId(i2, k2, j2);
-                i2 += k1;
-                j2 += j;
-                if (l2 == 0 && this.k(i2, k2, j2) <= this.random.nextInt(8) && this.a(EnumSkyBlock.SKY, i2, k2, j2) <= 0) {
-                    EntityHuman entityhuman1 = this.findNearbyPlayer((double) i2 + 0.5D, (double) k2 + 0.5D, (double) j2 + 0.5D, 8.0D);
-
-                    if (entityhuman1 != null && entityhuman1.e((double) i2 + 0.5D, (double) k2 + 0.5D, (double) j2 + 0.5D) > 4.0D) {
-                        this.makeSound((double) i2 + 0.5D, (double) k2 + 0.5D, (double) j2 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.random.nextFloat() * 0.2F);
-                        this.U = this.random.nextInt(12000) + 6000;
-                    }
-                }
-            }
-
+            this.a(k, l, chunk);
             // MethodProfiler.b("thunder"); // CraftBukkit - not in production code
-            if (this.random.nextInt(100000) == 0 && this.w() && this.v()) {
-                this.l = this.l * 3 + 1013904223;
-                l1 = this.l >> 2;
-                i2 = k1 + (l1 & 15);
-                j2 = j + (l1 >> 8 & 15);
-                k2 = this.e(i2, j2);
-                if (this.v(i2, k2, j2)) {
-                    this.strikeLightning(new EntityWeatherLighting(this, (double) i2, (double) k2, (double) j2));
-                    this.r = 2;
+            int i1;
+            int j1;
+            int k1;
+            int l1;
+
+            if (this.random.nextInt(100000) == 0 && this.x() && this.w()) {
+                this.g = this.g * 3 + 1013904223;
+                i1 = this.g >> 2;
+                j1 = k + (i1 & 15);
+                k1 = l + (i1 >> 8 & 15);
+                l1 = this.f(j1, k1);
+                if (this.y(j1, l1, k1)) {
+                    this.strikeLightning(new EntityWeatherLighting(this, (double) j1, (double) l1, (double) k1));
+                    this.m = 2;
                 }
             }
 
             // MethodProfiler.b("iceandsnow"); // CraftBukkit - not in production code
             if (this.random.nextInt(16) == 0) {
-                this.l = this.l * 3 + 1013904223;
-                l1 = this.l >> 2;
-                i2 = l1 & 15;
-                j2 = l1 >> 8 & 15;
-                k2 = this.e(i2 + k1, j2 + j);
-                if (this.q(i2 + k1, k2 - 1, j2 + j)) {
+                this.g = this.g * 3 + 1013904223;
+                i1 = this.g >> 2;
+                j1 = i1 & 15;
+                k1 = i1 >> 8 & 15;
+                l1 = this.f(j1 + k, k1 + l);
+                if (this.t(j1 + k, l1 - 1, k1 + l)) {
                     // CraftBukkit start
-                    BlockState blockState = this.getWorld().getBlockAt(i2 + k1, k2 - 1, j2 + j).getState();
+                    BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1 - 1, k1 + l).getState();
                     blockState.setTypeId(Block.ICE.id);
 
                     BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState);
@@ -1970,9 +1999,9 @@ public class World implements IBlockAccess {
                     // CraftBukkit end
                 }
 
-                if (this.w() && this.r(i2 + k1, k2, j2 + j)) {
+                if (this.x() && this.u(j1 + k, l1, k1 + l)) {
                     // CraftBukkit start
-                    BlockState blockState = this.getWorld().getBlockAt(i2 + k1, k2, j2 + j).getState();
+                    BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1, k1 + l).getState();
                     blockState.setTypeId(Block.SNOW.id);
 
                     BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState);
@@ -1984,22 +2013,31 @@ public class World implements IBlockAccess {
                 }
             }
 
-            // MethodProfiler.b("checkLight"); // CraftBukkit - not in production code
-            this.s(k1 + this.random.nextInt(16), this.random.nextInt(this.height), j + this.random.nextInt(16));
             // MethodProfiler.b("tickTiles"); // CraftBukkit - not in production code
+            ChunkSection[] achunksection = chunk.h();
 
-            for (l1 = 0; l1 < 20; ++l1) {
-                this.l = this.l * 3 + 1013904223;
-                i2 = this.l >> 2;
-                j2 = i2 & 15;
-                k2 = i2 >> 8 & 15;
-                l2 = i2 >> 16 & this.heightMinusOne;
-                int i3 = chunk.blocks[j2 << this.heightBitsPlusFour | k2 << this.heightBits | l2] & 255;
+            j1 = achunksection.length;
 
-                ++j1;
-                if (Block.n[i3]) {
-                    ++i;
-                    Block.byId[i3].a(this, j2 + k1, l2, k2 + j, this.random);
+            for (k1 = 0; k1 < j1; ++k1) {
+                ChunkSection chunksection = achunksection[k1];
+
+                if (chunksection != null && chunksection.b()) {
+                    for (int i2 = 0; i2 < 3; ++i2) {
+                        this.g = this.g * 3 + 1013904223;
+                        int j2 = this.g >> 2;
+                        int k2 = j2 & 15;
+                        int l2 = j2 >> 8 & 15;
+                        int i3 = j2 >> 16 & 15;
+                        int j3 = chunksection.a(k2, i3, l2);
+
+                        ++j;
+                        Block block = Block.byId[j3];
+
+                        if (block != null && block.m()) {
+                            ++i;
+                            block.a(this, k2 + k, i3 + chunksection.c(), l2 + l, this.random);
+                        }
+                    }
                 }
             }
 
@@ -2007,21 +2045,22 @@ public class World implements IBlockAccess {
         }
     }
 
-    public boolean p(int i, int j, int k) {
+    public boolean s(int i, int j, int k) {
         return this.c(i, j, k, false);
     }
 
-    public boolean q(int i, int j, int k) {
+    public boolean t(int i, int j, int k) {
         return this.c(i, j, k, true);
     }
 
     public boolean c(int i, int j, int k, boolean flag) {
-        float f = this.getWorldChunkManager().a(i, j, k);
+        BiomeBase biomebase = this.getBiome(i, k);
+        float f = biomebase.h();
 
         if (f > 0.15F) {
             return false;
         } else {
-            if (j >= 0 && j < this.height && this.a(EnumSkyBlock.BLOCK, i, j, k) < 10) {
+            if (j >= 0 && j < 256 && this.a(EnumSkyBlock.BLOCK, i, j, k) < 10) {
                 int l = this.getTypeId(i, j, k);
 
                 if ((l == Block.STATIONARY_WATER.id || l == Block.WATER.id) && this.getData(i, j, k) == 0) {
@@ -2057,13 +2096,14 @@ public class World implements IBlockAccess {
         }
     }
 
-    public boolean r(int i, int j, int k) {
-        float f = this.getWorldChunkManager().a(i, j, k);
+    public boolean u(int i, int j, int k) {
+        BiomeBase biomebase = this.getBiome(i, k);
+        float f = biomebase.h();
 
         if (f > 0.15F) {
             return false;
         } else {
-            if (j >= 0 && j < this.height && this.a(EnumSkyBlock.BLOCK, i, j, k) < 10) {
+            if (j >= 0 && j < 256 && this.a(EnumSkyBlock.BLOCK, i, j, k) < 10) {
                 int l = this.getTypeId(i, j - 1, k);
                 int i1 = this.getTypeId(i, j, k);
 
@@ -2076,15 +2116,15 @@ public class World implements IBlockAccess {
         }
     }
 
-    public void s(int i, int j, int k) {
-        if (!this.worldProvider.f) {
+    public void v(int i, int j, int k) {
+        if (!this.worldProvider.e) {
             this.b(EnumSkyBlock.SKY, i, j, k);
         }
 
         this.b(EnumSkyBlock.BLOCK, i, j, k);
     }
 
-    private int d(int i, int j, int k, int l, int i1, int j1) {
+    private int c(int i, int j, int k, int l, int i1, int j1) {
         int k1 = 0;
 
         if (this.isChunkLoaded(j, k, l)) {
@@ -2094,23 +2134,42 @@ public class World implements IBlockAccess {
                 j1 = 1;
             }
 
-            for (int l1 = 0; l1 < 6; ++l1) {
-                int i2 = l1 % 2 * 2 - 1;
-                int j2 = j + l1 / 2 % 3 / 2 * i2;
-                int k2 = k + (l1 / 2 + 1) % 3 / 2 * i2;
-                int l2 = l + (l1 / 2 + 2) % 3 / 2 * i2;
-                int i3 = this.a(EnumSkyBlock.SKY, j2, k2, l2) - j1;
+            int l1 = this.a(EnumSkyBlock.SKY, j - 1, k, l) - j1;
+            int i2 = this.a(EnumSkyBlock.SKY, j + 1, k, l) - j1;
+            int j2 = this.a(EnumSkyBlock.SKY, j, k - 1, l) - j1;
+            int k2 = this.a(EnumSkyBlock.SKY, j, k + 1, l) - j1;
+            int l2 = this.a(EnumSkyBlock.SKY, j, k, l - 1) - j1;
+            int i3 = this.a(EnumSkyBlock.SKY, j, k, l + 1) - j1;
 
-                if (i3 > k1) {
-                    k1 = i3;
-                }
+            if (l1 > k1) {
+                k1 = l1;
+            }
+
+            if (i2 > k1) {
+                k1 = i2;
+            }
+
+            if (j2 > k1) {
+                k1 = j2;
+            }
+
+            if (k2 > k1) {
+                k1 = k2;
+            }
+
+            if (l2 > k1) {
+                k1 = l2;
+            }
+
+            if (i3 > k1) {
+                k1 = i3;
             }
         }
 
         return k1;
     }
 
-    private int e(int i, int j, int k, int l, int i1, int j1) {
+    private int d(int i, int j, int k, int l, int i1, int j1) {
         int k1 = Block.lightEmission[i1];
         int l1 = this.a(EnumSkyBlock.BLOCK, j - 1, k, l) - j1;
         int i2 = this.a(EnumSkyBlock.BLOCK, j + 1, k, l) - j1;
@@ -2150,10 +2209,12 @@ public class World implements IBlockAccess {
         if (this.areChunksLoaded(i, j, k, 17)) {
             int l = 0;
             int i1 = 0;
+
+            // MethodProfiler.a("getBrightness"); // CraftBukkit - not in production code
             int j1 = this.a(enumskyblock, i, j, k);
             boolean flag = false;
             int k1 = this.getTypeId(i, j, k);
-            int l1 = Block.lightBlock[k1];
+            int l1 = this.f(i, j, k);
 
             if (l1 == 0) {
                 l1 = 1;
@@ -2163,9 +2224,9 @@ public class World implements IBlockAccess {
             int i2;
 
             if (enumskyblock == EnumSkyBlock.SKY) {
-                i2 = this.d(j1, i, j, k, k1, l1);
+                i2 = this.c(j1, i, j, k, k1, l1);
             } else {
-                i2 = this.e(j1, i, j, k, k1, l1);
+                i2 = this.d(j1, i, j, k, k1, l1);
             }
 
             int j2;
@@ -2176,16 +2237,16 @@ public class World implements IBlockAccess {
             int k3;
 
             if (i2 > j1) {
-                this.H[i1++] = 133152;
+                this.E[i1++] = 133152;
             } else if (i2 < j1) {
                 if (enumskyblock != EnumSkyBlock.BLOCK) {
                     ;
                 }
 
-                this.H[i1++] = 133152 + (j1 << 18);
+                this.E[i1++] = 133152 + (j1 << 18);
 
                 while (l < i1) {
-                    j2 = this.H[l++];
+                    j2 = this.E[l++];
                     k1 = (j2 & 63) - 32 + i;
                     l1 = (j2 >> 6 & 63) - 32 + j;
                     i2 = (j2 >> 12 & 63) - 32 + k;
@@ -2223,8 +2284,8 @@ public class World implements IBlockAccess {
                                         i5 = 1;
                                     }
 
-                                    if (l2 == k2 - i5) {
-                                        this.H[i1++] = j4 - i + 32 + (k4 - j + 32 << 6) + (l4 - k + 32 << 12) + (k2 - i5 << 18);
+                                    if (l2 == k2 - i5 && i1 <= this.E.length) {
+                                        this.E[i1++] = j4 - i + 32 + (k4 - j + 32 << 6) + (l4 - k + 32 << 12) + (k2 - i5 << 18);
                                     }
                                 }
                             }
@@ -2235,8 +2296,11 @@ public class World implements IBlockAccess {
                 l = 0;
             }
 
+            // MethodProfiler.a(); // CraftBukkit - not in production code
+            // MethodProfiler.a("tcp < tcc"); // CraftBukkit - not in production code
+
             while (l < i1) {
-                j1 = this.H[l++];
+                j1 = this.E[l++];
                 int j5 = (j1 & 63) - 32 + i;
 
                 j2 = (j1 >> 6 & 63) - 32 + j;
@@ -2251,9 +2315,9 @@ public class World implements IBlockAccess {
                 boolean flag2 = false;
 
                 if (enumskyblock == EnumSkyBlock.SKY) {
-                    l2 = this.d(l1, j5, j2, k1, i2, k2);
+                    l2 = this.c(l1, j5, j2, k1, i2, k2);
                 } else {
-                    l2 = this.e(l1, j5, j2, k1, i2, k2);
+                    l2 = this.d(l1, j5, j2, k1, i2, k2);
                 }
 
                 if (l2 != l1) {
@@ -2274,41 +2338,43 @@ public class World implements IBlockAccess {
                             j3 = -j3;
                         }
 
-                        if (i3 + k3 + j3 < 17 && i1 < this.H.length - 6) {
+                        if (i3 + k3 + j3 < 17 && i1 < this.E.length - 6) {
                             if (this.a(enumskyblock, j5 - 1, j2, k1) < l2) {
-                                this.H[i1++] = j5 - 1 - i + 32 + (j2 - j + 32 << 6) + (k1 - k + 32 << 12);
+                                this.E[i1++] = j5 - 1 - i + 32 + (j2 - j + 32 << 6) + (k1 - k + 32 << 12);
                             }
 
                             if (this.a(enumskyblock, j5 + 1, j2, k1) < l2) {
-                                this.H[i1++] = j5 + 1 - i + 32 + (j2 - j + 32 << 6) + (k1 - k + 32 << 12);
+                                this.E[i1++] = j5 + 1 - i + 32 + (j2 - j + 32 << 6) + (k1 - k + 32 << 12);
                             }
 
                             if (this.a(enumskyblock, j5, j2 - 1, k1) < l2) {
-                                this.H[i1++] = j5 - i + 32 + (j2 - 1 - j + 32 << 6) + (k1 - k + 32 << 12);
+                                this.E[i1++] = j5 - i + 32 + (j2 - 1 - j + 32 << 6) + (k1 - k + 32 << 12);
                             }
 
                             if (this.a(enumskyblock, j5, j2 + 1, k1) < l2) {
-                                this.H[i1++] = j5 - i + 32 + (j2 + 1 - j + 32 << 6) + (k1 - k + 32 << 12);
+                                this.E[i1++] = j5 - i + 32 + (j2 + 1 - j + 32 << 6) + (k1 - k + 32 << 12);
                             }
 
                             if (this.a(enumskyblock, j5, j2, k1 - 1) < l2) {
-                                this.H[i1++] = j5 - i + 32 + (j2 - j + 32 << 6) + (k1 - 1 - k + 32 << 12);
+                                this.E[i1++] = j5 - i + 32 + (j2 - j + 32 << 6) + (k1 - 1 - k + 32 << 12);
                             }
 
                             if (this.a(enumskyblock, j5, j2, k1 + 1) < l2) {
-                                this.H[i1++] = j5 - i + 32 + (j2 - j + 32 << 6) + (k1 + 1 - k + 32 << 12);
+                                this.E[i1++] = j5 - i + 32 + (j2 - j + 32 << 6) + (k1 + 1 - k + 32 << 12);
                             }
                         }
                     }
                 }
             }
+
+            // MethodProfiler.a(); // CraftBukkit - not in production code
         }
     }
 
     public boolean a(boolean flag) {
-        int i = this.K.size();
+        int i = this.H.size();
 
-        if (i != this.L.size()) {
+        if (i != this.I.size()) {
             throw new IllegalStateException("TickNextTick list out of synch");
         } else {
             if (i > 1000) {
@@ -2322,14 +2388,14 @@ public class World implements IBlockAccess {
             }
 
             for (int j = 0; j < i; ++j) {
-                NextTickListEntry nextticklistentry = (NextTickListEntry) this.K.first();
+                NextTickListEntry nextticklistentry = (NextTickListEntry) this.H.first();
 
                 if (!flag && nextticklistentry.e > this.worldData.getTime()) {
                     break;
                 }
 
-                this.K.remove(nextticklistentry);
-                this.L.remove(nextticklistentry);
+                this.H.remove(nextticklistentry);
+                this.I.remove(nextticklistentry);
                 byte b0 = 8;
 
                 if (this.a(nextticklistentry.a - b0, nextticklistentry.b - b0, nextticklistentry.c - b0, nextticklistentry.a + b0, nextticklistentry.b + b0, nextticklistentry.c + b0)) {
@@ -2341,25 +2407,25 @@ public class World implements IBlockAccess {
                 }
             }
 
-            return this.K.size() != 0;
+            return this.H.size() != 0;
         }
     }
 
     public List a(Chunk chunk, boolean flag) {
         ArrayList arraylist = null;
-        ChunkCoordIntPair chunkcoordintpair = chunk.j();
+        ChunkCoordIntPair chunkcoordintpair = chunk.k();
         int i = chunkcoordintpair.x << 4;
         int j = i + 16;
         int k = chunkcoordintpair.z << 4;
         int l = k + 16;
-        Iterator iterator = this.L.iterator();
+        Iterator iterator = this.I.iterator();
 
         while (iterator.hasNext()) {
             NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next();
 
             if (nextticklistentry.a >= i && nextticklistentry.a < j && nextticklistentry.c >= k && nextticklistentry.c < l) {
                 if (flag) {
-                    this.K.remove(nextticklistentry);
+                    this.H.remove(nextticklistentry);
                     iterator.remove();
                 }
 
@@ -2375,7 +2441,7 @@ public class World implements IBlockAccess {
     }
 
     public List getEntities(Entity entity, AxisAlignedBB axisalignedbb) {
-        this.V.clear();
+        this.S.clear();
         int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D);
         int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D);
         int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D);
@@ -2384,12 +2450,12 @@ public class World implements IBlockAccess {
         for (int i1 = i; i1 <= j; ++i1) {
             for (int j1 = k; j1 <= l; ++j1) {
                 if (this.isChunkLoaded(i1, j1)) {
-                    this.getChunkAt(i1, j1).a(entity, axisalignedbb, this.V);
+                    this.getChunkAt(i1, j1).a(entity, axisalignedbb, this.S);
                 }
             }
         }
 
-        return this.V;
+        return this.S;
     }
 
     public List a(Class oclass, AxisAlignedBB axisalignedbb) {
@@ -2410,13 +2476,35 @@ public class World implements IBlockAccess {
         return arraylist;
     }
 
-    public void b(int i, int j, int k, TileEntity tileentity) {
-        if (this.isLoaded(i, j, k)) {
-            this.getChunkAtWorldCoords(i, k).f();
+    public Entity a(Class oclass, AxisAlignedBB axisalignedbb, Entity entity) {
+        List list = this.a(oclass, axisalignedbb);
+        Entity entity1 = null;
+        double d0 = Double.MAX_VALUE;
+        Iterator iterator = list.iterator();
+
+        while (iterator.hasNext()) {
+            Entity entity2 = (Entity) iterator.next();
+
+            if (entity2 != entity) {
+                double d1 = entity.j(entity2);
+
+                if (d1 <= d0) {
+                    entity1 = entity2;
+                    d0 = d1;
+                }
+            }
         }
 
-        for (int l = 0; l < this.z.size(); ++l) {
-            ((IWorldAccess) this.z.get(l)).a(i, j, k, tileentity);
+        return entity1;
+    }
+
+    public void b(int i, int j, int k, TileEntity tileentity) {
+        if (this.isLoaded(i, j, k)) {
+            this.getChunkAtWorldCoords(i, k).e();
+        }
+
+        for (int l = 0; l < this.u.size(); ++l) {
+            ((IWorldAccess) this.u.get(l)).a(i, j, k, tileentity);
         }
     }
 
@@ -2449,7 +2537,7 @@ public class World implements IBlockAccess {
     }
 
     public void b(List list) {
-        this.J.addAll(list);
+        this.G.addAll(list);
     }
 
     public boolean mayPlace(int i, int j, int k, int l, boolean flag, int i1) {
@@ -2482,10 +2570,10 @@ public class World implements IBlockAccess {
         // CraftBukkit end
     }
 
-    public PathEntity findPath(Entity entity, Entity entity1, float f) {
+    public PathEntity findPath(Entity entity, Entity entity1, float f, boolean flag, boolean flag1, boolean flag2, boolean flag3) {
         // MethodProfiler.a("pathfind"); // CraftBukkit - not in production code
         int i = MathHelper.floor(entity.locX);
-        int j = MathHelper.floor(entity.locY);
+        int j = MathHelper.floor(entity.locY + 1.0D);
         int k = MathHelper.floor(entity.locZ);
         int l = (int) (f + 16.0F);
         int i1 = i - l;
@@ -2495,13 +2583,13 @@ public class World implements IBlockAccess {
         int i2 = j + l;
         int j2 = k + l;
         ChunkCache chunkcache = new ChunkCache(this, i1, j1, k1, l1, i2, j2);
-        PathEntity pathentity = (new Pathfinder(chunkcache)).a(entity, entity1, f);
+        PathEntity pathentity = (new Pathfinder(chunkcache, flag, flag1, flag2, flag3)).a(entity, entity1, f);
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
         return pathentity;
     }
 
-    public PathEntity a(Entity entity, int i, int j, int k, float f) {
+    public PathEntity a(Entity entity, int i, int j, int k, float f, boolean flag, boolean flag1, boolean flag2, boolean flag3) {
         // MethodProfiler.a("pathfind"); // CraftBukkit - not in production code
         int l = MathHelper.floor(entity.locX);
         int i1 = MathHelper.floor(entity.locY);
@@ -2514,7 +2602,7 @@ public class World implements IBlockAccess {
         int l2 = i1 + k1;
         int i3 = j1 + k1;
         ChunkCache chunkcache = new ChunkCache(this, l1, i2, j2, k2, l2, i3);
-        PathEntity pathentity = (new Pathfinder(chunkcache)).a(entity, i, j, k, f);
+        PathEntity pathentity = (new Pathfinder(chunkcache, flag, flag1, flag2, flag3)).a(entity, i, j, k, f);
 
         // MethodProfiler.a(); // CraftBukkit - not in production code
         return pathentity;
@@ -2570,6 +2658,23 @@ public class World implements IBlockAccess {
         return entityhuman;
     }
 
+    public EntityHuman a(double d0, double d1, double d2) {
+        double d3 = -1.0D;
+        EntityHuman entityhuman = null;
+
+        for (int i = 0; i < this.players.size(); ++i) {
+            EntityHuman entityhuman1 = (EntityHuman) this.players.get(i);
+            double d4 = entityhuman1.e(d0, entityhuman1.locY, d1);
+
+            if ((d2 < 0.0D || d4 < d2 * d2) && (d3 == -1.0D || d4 < d3)) {
+                d3 = d4;
+                entityhuman = entityhuman1;
+            }
+        }
+
+        return entityhuman;
+    }
+
     public EntityHuman findNearbyVulnerablePlayer(Entity entity, double d0) {
         return this.findNearbyVulnerablePlayer(entity.locX, entity.locY, entity.locZ, d0);
     }
@@ -2607,56 +2712,7 @@ public class World implements IBlockAccess {
         return null;
     }
 
-    public byte[] getMultiChunkData(int i, int j, int k, int l, int i1, int j1) {
-        byte[] abyte = new byte[l * i1 * j1 * 5 / 2];
-        int k1 = i >> 4;
-        int l1 = k >> 4;
-        int i2 = i + l - 1 >> 4;
-        int j2 = k + j1 - 1 >> 4;
-        int k2 = 0;
-        int l2 = j;
-        int i3 = j + i1;
-
-        if (j < 0) {
-            l2 = 0;
-        }
-
-        if (i3 > this.height) {
-            i3 = this.height;
-        }
-
-        for (int j3 = k1; j3 <= i2; ++j3) {
-            int k3 = i - j3 * 16;
-            int l3 = i + l - j3 * 16;
-
-            if (k3 < 0) {
-                k3 = 0;
-            }
-
-            if (l3 > 16) {
-                l3 = 16;
-            }
-
-            for (int i4 = l1; i4 <= j2; ++i4) {
-                int j4 = k - i4 * 16;
-                int k4 = k + j1 - i4 * 16;
-
-                if (j4 < 0) {
-                    j4 = 0;
-                }
-
-                if (k4 > 16) {
-                    k4 = 16;
-                }
-
-                k2 = this.getChunkAt(j3, i4).getData(abyte, k3, l2, j4, l3, i3, k4, k2);
-            }
-        }
-
-        return abyte;
-    }
-
-    public void l() {
+    public void m() {
         this.dataManager.checkSession();
     }
 
@@ -2669,7 +2725,7 @@ public class World implements IBlockAccess {
 
         NextTickListEntry nextticklistentry;
 
-        for (Iterator iterator = this.L.iterator(); iterator.hasNext(); nextticklistentry.e += j) {
+        for (Iterator iterator = this.I.iterator(); iterator.hasNext(); nextticklistentry.e += j) {
             nextticklistentry = (NextTickListEntry) iterator.next();
         }
 
@@ -2694,7 +2750,7 @@ public class World implements IBlockAccess {
 
     public void broadcastEntityEffect(Entity entity, byte b0) {}
 
-    public IChunkProvider p() {
+    public IChunkProvider q() {
         return this.chunkProvider;
     }
 
@@ -2715,7 +2771,7 @@ public class World implements IBlockAccess {
     }
 
     public void everyoneSleeping() {
-        this.Q = !this.players.isEmpty();
+        this.N = !this.players.isEmpty();
         Iterator iterator = this.players.iterator();
 
         while (iterator.hasNext()) {
@@ -2723,7 +2779,7 @@ public class World implements IBlockAccess {
 
             // CraftBukkit
             if (!entityhuman.isSleeping() && !entityhuman.fauxSleeping) {
-                this.Q = false;
+                this.N = false;
                 break;
             }
         }
@@ -2739,8 +2795,8 @@ public class World implements IBlockAccess {
     }
     // CraftBukkit end
 
-    protected void t() {
-        this.Q = false;
+    protected void u() {
+        this.N = false;
         Iterator iterator = this.players.iterator();
 
         while (iterator.hasNext()) {
@@ -2751,11 +2807,11 @@ public class World implements IBlockAccess {
             }
         }
 
-        this.A();
+        this.C();
     }
 
     public boolean everyoneDeeplySleeping() {
-        if (this.Q && !this.isStatic) {
+        if (this.N && !this.isStatic) {
             Iterator iterator = this.players.iterator();
 
             // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers
@@ -2784,35 +2840,41 @@ public class World implements IBlockAccess {
     }
 
     public float c(float f) {
-        return (this.p + (this.q - this.p) * f) * this.d(f);
+        return (this.k + (this.l - this.k) * f) * this.d(f);
     }
 
     public float d(float f) {
-        return this.n + (this.o - this.n) * f;
-    }
-
-    public boolean v() {
-        return (double) this.c(1.0F) > 0.9D;
+        return this.i + (this.j - this.i) * f;
     }
 
     public boolean w() {
+        return (double) this.c(1.0F) > 0.9D;
+    }
+
+    public boolean x() {
         return (double) this.d(1.0F) > 0.2D;
     }
 
-    public boolean v(int i, int j, int k) {
-        if (!this.w()) {
+    public boolean y(int i, int j, int k) {
+        if (!this.x()) {
             return false;
         } else if (!this.isChunkLoaded(i, j, k)) {
             return false;
-        } else if (this.e(i, k) > j) {
+        } else if (this.f(i, k) > j) {
             return false;
         } else {
-            BiomeBase biomebase = this.getWorldChunkManager().getBiome(i, k);
+            BiomeBase biomebase = this.getBiome(i, k);
 
             return biomebase.b() ? false : biomebase.c();
         }
     }
 
+    public boolean z(int i, int j, int k) {
+        BiomeBase biomebase = this.getBiome(i, k);
+
+        return biomebase.d();
+    }
+
     public void a(String s, WorldMapBase worldmapbase) {
         this.worldMaps.a(s, worldmapbase);
     }
@@ -2830,12 +2892,16 @@ public class World implements IBlockAccess {
     }
 
     public void a(EntityHuman entityhuman, int i, int j, int k, int l, int i1) {
-        for (int j1 = 0; j1 < this.z.size(); ++j1) {
-            ((IWorldAccess) this.z.get(j1)).a(entityhuman, i, j, k, l, i1);
+        for (int j1 = 0; j1 < this.u.size(); ++j1) {
+            ((IWorldAccess) this.u.get(j1)).a(entityhuman, i, j, k, l, i1);
         }
     }
 
-    public Random w(int i, int j, int k) {
+    public int getHeight() {
+        return 256;
+    }
+
+    public Random A(int i, int j, int k) {
         long l = (long) i * 341873128712L + (long) j * 132897987541L + this.getWorldData().getSeed() + (long) k;
 
         this.random.setSeed(l);
@@ -2846,16 +2912,14 @@ public class World implements IBlockAccess {
         return false;
     }
 
-    public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l, int i1, int j1) {}
-
     public BiomeMeta a(EnumCreatureType enumcreaturetype, int i, int j, int k) {
-        List list = this.p().getMobsFor(enumcreaturetype, i, j, k);
+        List list = this.q().getMobsFor(enumcreaturetype, i, j, k);
 
         return list != null && !list.isEmpty() ? (BiomeMeta) WeightedRandom.a(this.random, (Collection) list) : null;
     }
 
     public ChunkPosition b(String s, int i, int j, int k) {
-        return this.p().findNearestMapFeature(this, s, i, j, k);
+        return this.q().findNearestMapFeature(this, s, i, j, k);
     }
 
     // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/WorldData.java b/src/main/java/net/minecraft/server/WorldData.java
index 196fac1b49..6cdb5722ae 100644
--- a/src/main/java/net/minecraft/server/WorldData.java
+++ b/src/main/java/net/minecraft/server/WorldData.java
@@ -34,6 +34,14 @@ public class WorldData {
             this.type = WorldType.getType(s);
             if (this.type == null) {
                 this.type = WorldType.NORMAL;
+            } else if (this.type.c()) {
+                int i = 0;
+
+                if (nbttagcompound.hasKey("generatorVersion")) {
+                    i = nbttagcompound.getInt("generatorVersion");
+                }
+
+                this.type = this.type.a(i);
             }
         }
 
@@ -126,6 +134,7 @@ public class WorldData {
     private void a(NBTTagCompound nbttagcompound, NBTTagCompound nbttagcompound1) {
         nbttagcompound.setLong("RandomSeed", this.seed);
         nbttagcompound.setString("generatorName", this.type.name());
+        nbttagcompound.setInt("generatorVersion", this.type.getVersion());
         nbttagcompound.setInt("GameType", this.gameType);
         nbttagcompound.setBoolean("MapFeatures", this.useMapFeatures);
         nbttagcompound.setInt("SpawnX", this.spawnX);
@@ -166,11 +175,7 @@ public class WorldData {
         return this.time;
     }
 
-    public long g() {
-        return this.sizeOnDisk;
-    }
-
-    public int h() {
+    public int g() {
         return this.dimension;
     }
 
@@ -178,10 +183,6 @@ public class WorldData {
         this.time = i;
     }
 
-    public void b(long i) {
-        this.sizeOnDisk = i;
-    }
-
     public void setSpawn(int i, int j, int k) {
         this.spawnX = i;
         this.spawnY = j;
@@ -192,7 +193,7 @@ public class WorldData {
         this.name = s;
     }
 
-    public int i() {
+    public int h() {
         return this.version;
     }
 
@@ -251,4 +252,8 @@ public class WorldData {
     public WorldType getType() {
         return this.type;
     }
+
+    public void setType(WorldType worldtype) {
+        this.type = worldtype;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/WorldGenForest.java b/src/main/java/net/minecraft/server/WorldGenForest.java
index 831a3b2598..e52f535b1f 100644
--- a/src/main/java/net/minecraft/server/WorldGenForest.java
+++ b/src/main/java/net/minecraft/server/WorldGenForest.java
@@ -24,7 +24,7 @@ public class WorldGenForest extends WorldGenerator {
         int l = random.nextInt(3) + 5;
         boolean flag = true;
 
-        if (j >= 1 && j + l + 1 <= world.getHeight()) { // CraftBukkit
+        if (j >= 1 && j + l + 1 <= 128) {
             int i1;
             int j1;
             int k1;
@@ -43,7 +43,7 @@ public class WorldGenForest extends WorldGenerator {
 
                 for (j1 = i - b0; j1 <= i + b0 && flag; ++j1) {
                     for (k1 = k - b0; k1 <= k + b0 && flag; ++k1) {
-                        if (i1 >= 0 && i1 < world.getHeight()) { // CraftBukkit
+                        if (i1 >= 0 && i1 < 128) {
                             l1 = world.getTypeId(j1, i1, k1);
                             if (l1 != 0 && l1 != Block.LEAVES.id) {
                                 flag = false;
@@ -59,8 +59,9 @@ public class WorldGenForest extends WorldGenerator {
                 return false;
             } else {
                 i1 = world.getTypeId(i, j - 1, k);
-                if ((i1 == Block.GRASS.id || i1 == Block.DIRT.id) && j < world.getHeight() - l - 1) { // CraftBukkit
+                if ((i1 == Block.GRASS.id || i1 == Block.DIRT.id) && j < 128 - l - 1) {
                     world.setRawTypeId(i, j - 1, k, Block.DIRT.id);
+
                     int i2;
 
                     for (i2 = j - 3 + l; i2 <= j + l; ++i2) {
@@ -73,7 +74,7 @@ public class WorldGenForest extends WorldGenerator {
                             for (int k2 = k - k1; k2 <= k + k1; ++k2) {
                                 int l2 = k2 - k;
 
-                                if ((Math.abs(j2) != k1 || Math.abs(l2) != k1 || random.nextInt(2) != 0 && j1 != 0) && !Block.o[world.getTypeId(l1, i2, k2)]) {
+                                if ((Math.abs(j2) != k1 || Math.abs(l2) != k1 || random.nextInt(2) != 0 && j1 != 0) && !Block.n[world.getTypeId(l1, i2, k2)]) {
                                     this.setTypeAndData(world, l1, i2, k2, Block.LEAVES.id, 2);
                                 }
                             }
diff --git a/src/main/java/net/minecraft/server/WorldGenHugeMushroom.java b/src/main/java/net/minecraft/server/WorldGenHugeMushroom.java
index ba18d55466..0873320bbd 100644
--- a/src/main/java/net/minecraft/server/WorldGenHugeMushroom.java
+++ b/src/main/java/net/minecraft/server/WorldGenHugeMushroom.java
@@ -14,10 +14,13 @@ public class WorldGenHugeMushroom extends WorldGenerator {
     private int a = -1;
 
     public WorldGenHugeMushroom(int i) {
+        super(true);
         this.a = i;
     }
 
-    public WorldGenHugeMushroom() {}
+    public WorldGenHugeMushroom() {
+        super(false);
+    }
 
     // CraftBukkit start - delegate to grow()
     public boolean a(World world, Random random, int i, int j, int k) {
@@ -35,7 +38,7 @@ public class WorldGenHugeMushroom extends WorldGenerator {
         int i1 = random.nextInt(3) + 4;
         boolean flag = true;
 
-        if (j >= 1 && j + i1 + 1 <= world.height) {
+        if (j >= 1 && j + i1 + 1 < 256) {
             int j1;
             int k1;
             int l1;
@@ -50,7 +53,7 @@ public class WorldGenHugeMushroom extends WorldGenerator {
 
                 for (k1 = i - b0; k1 <= i + b0 && flag; ++k1) {
                     for (l1 = k - b0; l1 <= k + b0 && flag; ++l1) {
-                        if (j1 >= 0 && j1 < world.height) {
+                        if (j1 >= 0 && j1 < 256) {
                             i2 = world.getTypeId(k1, j1, l1);
                             if (i2 != 0 && i2 != Block.LEAVES.id) {
                                 flag = false;
@@ -73,7 +76,7 @@ public class WorldGenHugeMushroom extends WorldGenerator {
                 } else {
                     // CraftBukkit start
                     if (event == null) {
-                        world.setRawTypeId(i, j - 1, k, Block.DIRT.id);
+                        world.setRawTypeIdAndData(i, j - 1, k, Block.DIRT.id, 0);
                     } else {
                         BlockState dirtState = bukkitWorld.getBlockAt(i, j - 1, k).getState();
                         dirtState.setTypeId(Block.DIRT.id);
@@ -158,7 +161,7 @@ public class WorldGenHugeMushroom extends WorldGenerator {
                                     l2 = 0;
                                 }
 
-                                if ((l2 != 0 || j >= j + i1 - 1) && !Block.o[world.getTypeId(i2, k1, k2)]) {
+                                if ((l2 != 0 || j >= j + i1 - 1) && !Block.n[world.getTypeId(i2, k1, k2)]) {
                                     // CraftBukkit start
                                     if (event == null) {
                                         world.setRawTypeIdAndData(i2, k1, k2, Block.BIG_MUSHROOM_1.id + l, l2);
@@ -176,7 +179,7 @@ public class WorldGenHugeMushroom extends WorldGenerator {
 
                     for (k1 = 0; k1 < i1; ++k1) {
                         l1 = world.getTypeId(i, j + k1, k);
-                        if (!Block.o[l1]) {
+                        if (!Block.n[l1]) {
                             // CraftBukkit start
                             if (event == null) {
                                 world.setRawTypeIdAndData(i, j + k1, k, Block.BIG_MUSHROOM_1.id + l, 10);
@@ -199,6 +202,7 @@ public class WorldGenHugeMushroom extends WorldGenerator {
                         }
                     }
                     // CraftBukkit end
+
                     return true;
                 }
             }
diff --git a/src/main/java/net/minecraft/server/WorldGenTaiga1.java b/src/main/java/net/minecraft/server/WorldGenTaiga1.java
index 237bc99daa..2a82880570 100644
--- a/src/main/java/net/minecraft/server/WorldGenTaiga1.java
+++ b/src/main/java/net/minecraft/server/WorldGenTaiga1.java
@@ -25,7 +25,7 @@ public class WorldGenTaiga1 extends WorldGenerator {
         int k1 = 1 + random.nextInt(j1 + 1);
         boolean flag = true;
 
-        if (j >= 1 && j + l + 1 <= world.getHeight()) { // CraftBukkit
+        if (j >= 1 && j + l + 1 <= 128) {
             int l1;
             int i2;
             int j2;
@@ -43,7 +43,7 @@ public class WorldGenTaiga1 extends WorldGenerator {
 
                 for (i2 = i - l2; i2 <= i + l2 && flag; ++i2) {
                     for (j2 = k - l2; j2 <= k + l2 && flag; ++j2) {
-                        if (l1 >= 0 && l1 < world.getHeight()) { // CraftBukkit
+                        if (l1 >= 0 && l1 < 128) {
                             k2 = world.getTypeId(i2, l1, j2);
                             if (k2 != 0 && k2 != Block.LEAVES.id) {
                                 flag = false;
@@ -59,7 +59,7 @@ public class WorldGenTaiga1 extends WorldGenerator {
                 return false;
             } else {
                 l1 = world.getTypeId(i, j - 1, k);
-                if ((l1 == Block.GRASS.id || l1 == Block.DIRT.id) && j < world.getHeight() - l - 1) { // CraftBukkit
+                if ((l1 == Block.GRASS.id || l1 == Block.DIRT.id) && j < 128 - l - 1) {
                     world.setRawTypeId(i, j - 1, k, Block.DIRT.id);
                     l2 = 0;
 
@@ -70,7 +70,7 @@ public class WorldGenTaiga1 extends WorldGenerator {
                             for (int i3 = k - l2; i3 <= k + l2; ++i3) {
                                 int j3 = i3 - k;
 
-                                if ((Math.abs(k2) != l2 || Math.abs(j3) != l2 || l2 <= 0) && !Block.o[world.getTypeId(j2, i2, i3)]) {
+                                if ((Math.abs(k2) != l2 || Math.abs(j3) != l2 || l2 <= 0) && !Block.n[world.getTypeId(j2, i2, i3)]) {
                                     world.setRawTypeIdAndData(j2, i2, i3, Block.LEAVES.id, 1);
                                 }
                             }
diff --git a/src/main/java/net/minecraft/server/WorldGenTaiga2.java b/src/main/java/net/minecraft/server/WorldGenTaiga2.java
index f7f92159d9..de9ce6ba85 100644
--- a/src/main/java/net/minecraft/server/WorldGenTaiga2.java
+++ b/src/main/java/net/minecraft/server/WorldGenTaiga2.java
@@ -27,7 +27,7 @@ public class WorldGenTaiga2 extends WorldGenerator {
         int k1 = 2 + random.nextInt(2);
         boolean flag = true;
 
-        if (j >= 1 && j + l + 1 <= world.getHeight()) { // CraftBukkit
+        if (j >= 1 && j + l + 1 <= 128) {
             int l1;
             int i2;
             int j2;
@@ -44,7 +44,7 @@ public class WorldGenTaiga2 extends WorldGenerator {
 
                 for (i2 = i - k2; i2 <= i + k2 && flag; ++i2) {
                     for (int l2 = k - k2; l2 <= k + k2 && flag; ++l2) {
-                        if (l1 >= 0 && l1 < world.getHeight()) { // CraftBukkit
+                        if (l1 >= 0 && l1 < 128) {
                             j2 = world.getTypeId(i2, l1, l2);
                             if (j2 != 0 && j2 != Block.LEAVES.id) {
                                 flag = false;
@@ -60,7 +60,7 @@ public class WorldGenTaiga2 extends WorldGenerator {
                 return false;
             } else {
                 l1 = world.getTypeId(i, j - 1, k);
-                if ((l1 == Block.GRASS.id || l1 == Block.DIRT.id) && j < world.getHeight() - l - 1) { // CraftBukkit
+                if ((l1 == Block.GRASS.id || l1 == Block.DIRT.id) && j < 128 - l - 1) {
                     world.setRawTypeId(i, j - 1, k, Block.DIRT.id);
                     k2 = random.nextInt(2);
                     i2 = 1;
@@ -78,7 +78,7 @@ public class WorldGenTaiga2 extends WorldGenerator {
                             for (int l3 = k - k2; l3 <= k + k2; ++l3) {
                                 int i4 = l3 - k;
 
-                                if ((Math.abs(k3) != k2 || Math.abs(i4) != k2 || k2 <= 0) && !Block.o[world.getTypeId(i3, j3, l3)]) {
+                                if ((Math.abs(k3) != k2 || Math.abs(i4) != k2 || k2 <= 0) && !Block.n[world.getTypeId(i3, j3, l3)]) {
                                     this.setTypeAndData(world, i3, j3, l3, Block.LEAVES.id, 1);
                                 }
                             }
diff --git a/src/main/java/net/minecraft/server/WorldGenTrees.java b/src/main/java/net/minecraft/server/WorldGenTrees.java
index 630f619bab..19abf24bf1 100644
--- a/src/main/java/net/minecraft/server/WorldGenTrees.java
+++ b/src/main/java/net/minecraft/server/WorldGenTrees.java
@@ -6,8 +6,21 @@ import org.bukkit.BlockChangeDelegate; // CraftBukkit
 
 public class WorldGenTrees extends WorldGenerator {
 
+    private final int a;
+    private final boolean b;
+    private final int c;
+    private final int d;
+
     public WorldGenTrees(boolean flag) {
+        this(flag, 4, 0, 0, false);
+    }
+
+    public WorldGenTrees(boolean flag, int i, int j, int k, boolean flag1) {
         super(flag);
+        this.a = i;
+        this.c = j;
+        this.d = k;
+        this.b = flag1;
     }
 
     public boolean a(World world, Random random, int i, int j, int k) {
@@ -21,18 +34,17 @@ public class WorldGenTrees extends WorldGenerator {
 
     public boolean generate(BlockChangeDelegate world, Random random, int i, int j, int k) {
         // CraftBukkit end
-        int l = random.nextInt(3) + 4;
+        int l = random.nextInt(3) + this.a;
         boolean flag = true;
 
-        if (j >= 1 && j + l + 1 <= world.getHeight()) { // CraftBukkit
+        if (j >= 1 && j + l + 1 <= 256) {
             int i1;
+            byte b0;
             int j1;
             int k1;
-            int l1;
 
             for (i1 = j; i1 <= j + 1 + l; ++i1) {
-                byte b0 = 1;
-
+                b0 = 1;
                 if (i1 == j) {
                     b0 = 0;
                 }
@@ -41,11 +53,11 @@ public class WorldGenTrees extends WorldGenerator {
                     b0 = 2;
                 }
 
-                for (j1 = i - b0; j1 <= i + b0 && flag; ++j1) {
-                    for (k1 = k - b0; k1 <= k + b0 && flag; ++k1) {
-                        if (i1 >= 0 && i1 < world.getHeight()) { // CraftBukkit
-                            l1 = world.getTypeId(j1, i1, k1);
-                            if (l1 != 0 && l1 != Block.LEAVES.id) {
+                for (int l1 = i - b0; l1 <= i + b0 && flag; ++l1) {
+                    for (j1 = k - b0; j1 <= k + b0 && flag; ++j1) {
+                        if (i1 >= 0 && i1 < 256) {
+                            k1 = world.getTypeId(l1, i1, j1);
+                            if (k1 != 0 && k1 != Block.LEAVES.id && k1 != Block.GRASS.id && k1 != Block.DIRT.id && k1 != Block.LOG.id) {
                                 flag = false;
                             }
                         } else {
@@ -59,32 +71,82 @@ public class WorldGenTrees extends WorldGenerator {
                 return false;
             } else {
                 i1 = world.getTypeId(i, j - 1, k);
-                if ((i1 == Block.GRASS.id || i1 == Block.DIRT.id) && j < world.getHeight() - l - 1) { // CraftBukkit
+                if ((i1 == Block.GRASS.id || i1 == Block.DIRT.id) && j < 256 - l - 1) {
                     world.setRawTypeId(i, j - 1, k, Block.DIRT.id);
+                    b0 = 3;
+                    byte b1 = 0;
 
                     int i2;
+                    int j2;
+                    int k2;
 
-                    for (i2 = j - 3 + l; i2 <= j + l; ++i2) {
-                        j1 = i2 - (j + l);
-                        k1 = 1 - j1 / 2;
+                    for (j1 = j - b0 + l; j1 <= j + l; ++j1) {
+                        k1 = j1 - (j + l);
+                        i2 = b1 + 1 - k1 / 2;
 
-                        for (l1 = i - k1; l1 <= i + k1; ++l1) {
-                            int j2 = l1 - i;
+                        for (j2 = i - i2; j2 <= i + i2; ++j2) {
+                            k2 = j2 - i;
 
-                            for (int k2 = k - k1; k2 <= k + k1; ++k2) {
-                                int l2 = k2 - k;
+                            for (int l2 = k - i2; l2 <= k + i2; ++l2) {
+                                int i3 = l2 - k;
 
-                                if ((Math.abs(j2) != k1 || Math.abs(l2) != k1 || random.nextInt(2) != 0 && j1 != 0) && !Block.o[world.getTypeId(l1, i2, k2)]) {
-                                    this.setTypeAndData(world, l1, i2, k2, Block.LEAVES.id, 0);
+                                if ((Math.abs(k2) != i2 || Math.abs(i3) != i2 || random.nextInt(2) != 0 && k1 != 0) && !Block.n[world.getTypeId(j2, j1, l2)]) {
+                                    this.setTypeAndData(world, j2, j1, l2, Block.LEAVES.id, this.d);
                                 }
                             }
                         }
                     }
 
-                    for (i2 = 0; i2 < l; ++i2) {
-                        j1 = world.getTypeId(i, j + i2, k);
-                        if (j1 == 0 || j1 == Block.LEAVES.id) {
-                            this.setTypeAndData(world, i, j + i2, k, Block.LOG.id, 0);
+                    for (j1 = 0; j1 < l; ++j1) {
+                        k1 = world.getTypeId(i, j + j1, k);
+                        if (k1 == 0 || k1 == Block.LEAVES.id) {
+                            this.setTypeAndData(world, i, j + j1, k, Block.LOG.id, this.c);
+                            if (this.b && j1 > 0) {
+                                if (random.nextInt(3) > 0 && ((World )world).isEmpty(i - 1, j + j1, k)) { // Craftbukkit cast to World
+                                    this.setTypeAndData(world, i - 1, j + j1, k, Block.VINE.id, 8);
+                                }
+
+                                if (random.nextInt(3) > 0 && ((World )world).isEmpty(i + 1, j + j1, k)) { // Craftbukkit cast to World
+                                    this.setTypeAndData(world, i + 1, j + j1, k, Block.VINE.id, 2);
+                                }
+
+                                if (random.nextInt(3) > 0 && ((World )world).isEmpty(i, j + j1, k - 1)) { // Craftbukkit cast to World
+                                    this.setTypeAndData(world, i, j + j1, k - 1, Block.VINE.id, 1);
+                                }
+
+                                if (random.nextInt(3) > 0 && ((World )world).isEmpty(i, j + j1, k + 1)) { // Craftbukkit cast to World
+                                    this.setTypeAndData(world, i, j + j1, k + 1, Block.VINE.id, 4);
+                                }
+                            }
+                        }
+                    }
+
+                    if (this.b) {
+                        for (j1 = j - 3 + l; j1 <= j + l; ++j1) {
+                            k1 = j1 - (j + l);
+                            i2 = 2 - k1 / 2;
+
+                            for (j2 = i - i2; j2 <= i + i2; ++j2) {
+                                for (k2 = k - i2; k2 <= k + i2; ++k2) {
+                                    if (world.getTypeId(j2, j1, k2) == Block.LEAVES.id) {
+                                        if (random.nextInt(4) == 0 && world.getTypeId(j2 - 1, j1, k2) == 0) {
+                                            this.a((World) world, j2 - 1, j1, k2, 8); // Craftbukkit cast to World
+                                        }
+
+                                        if (random.nextInt(4) == 0 && world.getTypeId(j2 + 1, j1, k2) == 0) {
+                                            this.a((World) world, j2 + 1, j1, k2, 2); // Craftbukkit cast to World
+                                        }
+
+                                        if (random.nextInt(4) == 0 && world.getTypeId(j2, j1, k2 - 1) == 0) {
+                                            this.a((World) world, j2, j1, k2 - 1, 1); // Craftbukkit cast to World
+                                        }
+
+                                        if (random.nextInt(4) == 0 && world.getTypeId(j2, j1, k2 + 1) == 0) {
+                                            this.a((World) world, j2, j1, k2 + 1, 4); // Craftbukkit cast to World
+                                        }
+                                    }
+                                }
+                            }
                         }
                     }
 
@@ -97,4 +159,19 @@ public class WorldGenTrees extends WorldGenerator {
             return false;
         }
     }
+
+    private void a(World world, int i, int j, int k, int l) {
+        world.setTypeIdAndData(i, j, k, Block.VINE.id, l);
+        int i1 = 4;
+
+        while (true) {
+            --j;
+            if (world.getTypeId(i, j, k) != 0 || i1 <= 0) {
+                return;
+            }
+
+            world.setTypeIdAndData(i, j, k, Block.VINE.id, l);
+            --i1;
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/server/WorldManager.java b/src/main/java/net/minecraft/server/WorldManager.java
index 74131332aa..98ea4b390c 100644
--- a/src/main/java/net/minecraft/server/WorldManager.java
+++ b/src/main/java/net/minecraft/server/WorldManager.java
@@ -28,6 +28,8 @@ public class WorldManager implements IWorldAccess {
         this.server.serverConfigurationManager.flagDirty(i, j, k, this.world.dimension); // CraftBukkit
     }
 
+    public void b(int i, int j, int k) {}
+
     public void a(String s, int i, int j, int k) {}
 
     public void a(int i, int j, int k, TileEntity tileentity) {
diff --git a/src/main/java/net/minecraft/server/WorldNBTStorage.java b/src/main/java/net/minecraft/server/WorldNBTStorage.java
index 4689db7efa..cfab080651 100644
--- a/src/main/java/net/minecraft/server/WorldNBTStorage.java
+++ b/src/main/java/net/minecraft/server/WorldNBTStorage.java
@@ -76,19 +76,7 @@ public class WorldNBTStorage implements PlayerFileData, IDataManager {
     }
 
     public IChunkLoader createChunkLoader(WorldProvider worldprovider) {
-        File file1;
-
-        if (worldprovider instanceof WorldProviderHell) {
-            file1 = new File(this.baseDir, "DIM-1");
-            file1.mkdirs();
-            return new ChunkLoader(file1, true);
-        } else if (worldprovider instanceof WorldProviderTheEnd) {
-            file1 = new File(this.baseDir, "DIM1");
-            file1.mkdirs();
-            return new ChunkLoader(file1, true);
-        } else {
-            return new ChunkLoader(this.baseDir, true);
-        }
+        throw new RuntimeException("Old Chunk Storage is no longer supported.");
     }
 
     public WorldData getWorldData() {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index d94751cba9..1321e4ef87 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -35,10 +35,6 @@ public class WorldServer extends World implements BlockChangeDelegate {
         this.manager = new PlayerManager(minecraftserver, this.dimension, minecraftserver.propertyManager.getInt("view-distance", 10));
     }
 
-    public int getHeight() {
-        return height;
-    }
-
     @Override
     public TileEntity getTileEntity(int i, int j, int k) {
         TileEntity result = super.getTileEntity(i, j, k);
@@ -174,7 +170,7 @@ public class WorldServer extends World implements BlockChangeDelegate {
     protected void c(Entity entity) {
         super.c(entity);
         this.entitiesById.a(entity.id, entity);
-        Entity[] aentity = entity.aR();
+        Entity[] aentity = entity.ba();
 
         if (aentity != null) {
             for (int i = 0; i < aentity.length; ++i) {
@@ -186,7 +182,7 @@ public class WorldServer extends World implements BlockChangeDelegate {
     protected void d(Entity entity) {
         super.d(entity);
         this.entitiesById.d(entity.id);
-        Entity[] aentity = entity.aR();
+        Entity[] aentity = entity.ba();
 
         if (aentity != null) {
             for (int i = 0; i < aentity.length; ++i) {
@@ -253,10 +249,10 @@ public class WorldServer extends World implements BlockChangeDelegate {
     }
 
     protected void i() {
-        boolean flag = this.w();
+        boolean flag = this.x();
 
         super.i();
-        if (flag != this.w()) {
+        if (flag != this.x()) {
             // CraftBukkit start - only sending weather packets to those affected
             for (int i = 0; i < this.players.size(); ++i) {
                 if (((EntityPlayer) this.players.get(i)).world == this) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index 36cc3a3797..0cfd5fe002 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -15,6 +15,7 @@ import org.bukkit.entity.Entity;
 import org.bukkit.ChunkSnapshot;
 import net.minecraft.server.BiomeBase;
 import net.minecraft.server.WorldChunkManager;
+import org.apache.commons.lang.NotImplementedException;
 
 public class CraftChunk implements Chunk {
     private WeakReference<net.minecraft.server.Chunk> weakChunk;
@@ -135,9 +136,11 @@ public class CraftChunk implements Chunk {
     public ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain) {
         net.minecraft.server.Chunk chunk = getHandle();
         byte[] buf = new byte[32768 + 16384 + 16384 + 16384]; // Get big enough buffer for whole chunk
-        chunk.getData(buf, 0, 0, 0, 16, 128, 16, 0); // Get whole chunk
+        //chunk.getData(buf, 0, 0, 0, 16, 128, 16, 0); // Get whole chunk
         byte[] hmap = null;
 
+        if (true) throw new NotImplementedException("Chunk snapshots do not yet work"); // TODO: Snapshots.
+
         if (includeMaxblocky) {
             hmap = new byte[256]; // Get copy of height map
             System.arraycopy(chunk.heightMap, 0, hmap, 0, 256);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index aaf1e1f6e9..7fd2ff2f89 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -939,11 +939,11 @@ public class CraftWorld implements World {
     }
 
     public int getMaxHeight() {
-        return world.height;
+        return world.getHeight();
     }
 
     public int getSeaLevel() {
-        return world.seaLevel;
+        return 64;
     }
 
     public boolean getKeepSpawnInMemory() {
diff --git a/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java b/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java
index 8abe81e148..495c586a08 100644
--- a/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java
+++ b/src/main/java/org/bukkit/craftbukkit/PortalTravelAgent.java
@@ -87,7 +87,7 @@ public class PortalTravelAgent implements TravelAgent {
             for (int k1 = i1 - this.searchRadius; k1 <= i1 + this.searchRadius; ++k1) {
                 double d3 = (double) k1 + 0.5D - location.getZ();
 
-                for (int l1 = world.height - 1; l1 >= 0; --l1) {
+                for (int l1 = 127; l1 >= 0; --l1) {
                     if (world.getTypeId(j1, l1, k1) == Block.PORTAL.id) {
                         while (world.getTypeId(j1, l1 - 1, k1) == Block.PORTAL.id) {
                             --l1;
@@ -194,7 +194,7 @@ public class PortalTravelAgent implements TravelAgent {
                 d2 = (double) j2 + 0.5D - location.getZ();
 
                 label271:
-                for (l2 = world.height - 1; l2 >= 0; --l2) {
+                for (l2 = 127; l2 >= 0; --l2) {
                     if (world.isEmpty(i2, l2, j2)) {
                         while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) {
                             --l2;
@@ -245,7 +245,7 @@ public class PortalTravelAgent implements TravelAgent {
                     d2 = (double) j2 + 0.5D - location.getZ();
 
                     label219:
-                    for (l2 = world.height - 1; l2 >= 0; --l2) {
+                    for (l2 = 127; l2 >= 0; --l2) {
                         if (world.isEmpty(i2, l2, j2)) {
                             while (l2 > 0 && world.isEmpty(i2, l2 - 1, j2)) {
                                 --l2;
@@ -306,8 +306,8 @@ public class PortalTravelAgent implements TravelAgent {
                 i1 = 70;
             }
 
-            if (i1 > world.height - 10) {
-                i1 = world.height - 10;
+            if (i1 > 118) {
+                i1 = 118;
             }
 
             j5 = i1;
@@ -353,8 +353,8 @@ public class PortalTravelAgent implements TravelAgent {
                 i1 = 70;
             }
 
-            if (i1 > world.height - 10) {
-                i1 = world.height - 10;
+            if (i1 > 118) {
+                i1 = 118;
             }
 
             j5 = i1;
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 02debb1c9a..89ffd25ff8 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -399,6 +399,8 @@ public class CraftBlock implements Block {
         BIOME_MAPPING[BiomeBase.FOREST_HILLS.id] = Biome.FOREST_HILLS;
         BIOME_MAPPING[BiomeBase.TAIGA_HILLS.id] = Biome.TAIGA_HILLS;
         BIOME_MAPPING[BiomeBase.SMALL_MOUNTAINS.id] = Biome.SMALL_MOUNTAINS;
+        BIOME_MAPPING[BiomeBase.JUNGLE.id] = Biome.JUNGLE;
+        BIOME_MAPPING[BiomeBase.JUNGLE_HILLS.id] = Biome.JUNGLE_HILLS;
         /* Sanity check - we should have a record for each record in the BiomeBase.a table */
         /* Helps avoid missed biomes when we upgrade bukkit to new code with new biomes */
         for (int i = 0; i < BIOME_MAPPING.length; i++) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java
index aa8bdb3b09..3fe70b4eed 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java
@@ -18,7 +18,7 @@ public class CraftCreature extends CraftLivingEntity implements Creature {
         } else if (target instanceof CraftLivingEntity) {
             EntityLiving victim = ((CraftLivingEntity) target).getHandle();
             entity.target = victim;
-            entity.pathEntity = entity.world.findPath(entity, entity.target, 16.0F);
+            entity.pathEntity = entity.world.findPath(entity, entity.target, 16.0F, true, false, false, true);
         }
     }
 
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 039cf9b57f..3f8a02d927 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -31,6 +31,7 @@ import net.minecraft.server.Packet61WorldEvent;
 import net.minecraft.server.Packet6SpawnPosition;
 import net.minecraft.server.Packet70Bed;
 import net.minecraft.server.WorldServer;
+import org.apache.commons.lang.NotImplementedException;
 import org.bukkit.Achievement;
 import org.bukkit.Material;
 import org.bukkit.Statistic;
@@ -286,6 +287,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
     public boolean sendChunkChange(Location loc, int sx, int sy, int sz, byte[] data) {
         if (getHandle().netServerHandler == null) return false;
 
+        /*
         int x = loc.getBlockX();
         int y = loc.getBlockY();
         int z = loc.getBlockZ();
@@ -310,6 +312,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
         getHandle().netServerHandler.sendPacket(packet);
 
         return true;
+        */
+
+        throw new NotImplementedException("Chunk changes do not yet work"); // TODO: Chunk changes.
     }
 
     public void sendMap(MapView map) {
@@ -798,4 +803,4 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
     public void disconnect(String reason) {
         conversationTracker.abandonAllConversations();
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
index 8a2360d077..a224153890 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
@@ -81,15 +81,9 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
     }
 
     public List<?> getMobsFor(EnumCreatureType type, int x, int y, int z) {
-        WorldChunkManager worldchunkmanager = world.getWorldChunkManager();
+        BiomeBase biomebase = world.getBiome(x, z);
 
-        if (worldchunkmanager == null) {
-            return null;
-        } else {
-            BiomeBase biomebase = worldchunkmanager.getBiome(new ChunkCoordIntPair(x >> 4, z >> 4));
-
-            return biomebase == null ? null : biomebase.getMobs(type);
-        }
+        return biomebase == null ? null : biomebase.getMobs(type);
     }
 
     public ChunkPosition findNearestMapFeature(World world, String type, int x, int y, int z) {
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java
index 0aba33fa3f..7db0689fa2 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java
@@ -73,6 +73,20 @@ public class CraftInventoryCustom extends CraftInventory {
             return result;
         }
 
+        public ItemStack splitWithoutUpdate(int i) {
+            ItemStack stack = this.getItem(i);
+            ItemStack result;
+            if (stack == null) return null;
+            if (stack.count <= 1) {
+                this.setItem(i, null);
+                result = stack;
+            } else {
+                result = new ItemStack(stack.id, 1, stack.getData());
+                stack.count -= 1;
+            }
+            return result;
+        }
+
         public void setItem(int i, ItemStack itemstack) {
             items[i] = itemstack;
         }