From dca17e2555b38342497193d6afb90c1d02b7f4ac Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Thu, 6 Jan 2011 06:20:12 -0500
Subject: [PATCH 01/27] Create a concept of a null item stack

By: durron597 <martin.jared@gmail.com>
---
 .../bukkit/craftbukkit/CraftItemStack.java    | 50 ++++++++++++++-----
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java
index ed80091064..3527721b05 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java
@@ -7,7 +7,7 @@ public class CraftItemStack extends ItemStack {
     protected net.minecraft.server.ItemStack item;
 
     public CraftItemStack(net.minecraft.server.ItemStack item) {
-        super(item.c, item.a);
+        super(item != null ? item.c : 0, item != null ? item.a : 0);
         this.item = item;
     }
 
@@ -18,44 +18,68 @@ public class CraftItemStack extends ItemStack {
 
     @Override
     public Material getType() {
-        super.setTypeID(item.c); // sync, needed?
+        super.setTypeID(item != null ? item.c : 0); // sync, needed?
         return super.getType();
     }
 
     @Override
     public int getTypeID() {
-        super.setTypeID(item.c); // sync, needed?
-        return item.c;
+        super.setTypeID(item != null ? item.c : 0); // sync, needed?
+        return item != null ? item.c : 0;
     }
 
     @Override
     public void setTypeID(int type) {
-        super.setTypeID(item.c);
-        item.c = type;
+        if (type == 0) {
+            super.setTypeID(0);
+            super.setAmount(0);
+            item = null;
+        } else {
+            if (item == null) {
+                item = new net.minecraft.server.ItemStack(type);
+                super.setAmount(1);
+            } else {
+                item.c = type;
+                super.setTypeID(item.c);
+            }
+        }
     }
 
     @Override
     public int getAmount() {
-        super.setAmount(item.a); // sync, needed?
+        super.setAmount(item != null ? item.a : 0); // sync, needed?
         return item.a;
     }
 
     @Override
     public void setAmount(int amount) {
-        super.setAmount(amount);
-        item.a = amount;
+        if (amount == 0) {
+            super.setTypeID(0);
+            super.setAmount(0);
+            item = null;
+        } else {
+            super.setAmount(amount);
+            item.a = amount;
+        }
     }
 
     @Override
     public void setDamage(final byte damage) {
-        super.setDamage(damage);
-        item.d = damage;
+        // Ignore damage if item is null
+        if (item != null) {
+            super.setDamage(damage);
+            item.d = damage;
+        } 
     }
 
     @Override
     public byte getDamage() {
-        super.setDamage((byte) item.d); // sync, needed?
-        return (byte) item.d;
+        if (item != null) {
+            super.setDamage((byte) item.d); // sync, needed?    
+            return (byte) item.d;
+        } else {
+            return 0;
+        }
     }
 
 }

From 87ab5dc0f8461d56d2bde0590cd228ba49e95b13 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 02:33:59 +0800
Subject: [PATCH 02/27] Fixed plugins being loaded before world.

By: FrozenCow <frozencow@gmail.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftServer.java     | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 4d814ed16f..11884e7140 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -26,7 +26,9 @@ public final class CraftServer implements Server {
         this.server = server;
 
         pluginManager.RegisterInterface(JavaPluginLoader.class);
-
+    }
+    
+    public void loadPlugins() {
         File pluginFolder = (File)console.options.valueOf("plugins");
 
         if (pluginFolder.exists()) {

From 99fcba15f0d267d2634c42392cdea737f8f0a9b4 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Thu, 6 Jan 2011 13:10:28 +0800
Subject: [PATCH 03/27] Added CraftServer.matchPlayer(String) - partial-name
 matching

By: Animosity <nullcline@gmail.com>
---
 .../org/bukkit/craftbukkit/CraftServer.java   | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 11884e7140..129749091a 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -80,6 +80,30 @@ public final class CraftServer implements Server {
     public Player getPlayer(final EntityPlayerMP entity) {
         return entity.a.getPlayer();
     }
+    
+    public Player matchPlayer(String wantedPlayerName) {
+        Player wantedPlayer = null;
+     
+        for (Player iterPlayer : this.getOnlinePlayers()) {
+            String iterPlayerName = iterPlayer.getName();
+
+            if (wantedPlayerName.equalsIgnoreCase(iterPlayerName)) {
+                // Exact match
+                wantedPlayer = this.getPlayer(wantedPlayerName);
+                break;
+            }
+            if (wantedPlayerName.toLowerCase().indexOf(iterPlayerName.toLowerCase()) != -1) {
+                // Partial match
+                if (wantedPlayer != null) {
+                    // Multiple matches
+                    return null;
+                }
+                wantedPlayer = iterPlayer;
+            }
+        }
+
+        return wantedPlayer;
+    }
 
     public PluginManager getPluginManager() {
         return pluginManager;

From f73b61f1ced588413dfaabc369fd76573d5a1197 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 10:42:53 +0800
Subject: [PATCH 04/27] Better implementation of matchPlayer(String) - return
 List of potential matches

By: Animosity <nullcline@gmail.com>
---
 .../org/bukkit/craftbukkit/CraftServer.java   | 27 +++++++++----------
 1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 129749091a..2d0d0c96eb 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1,6 +1,7 @@
 package org.bukkit.craftbukkit;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -81,28 +82,24 @@ public final class CraftServer implements Server {
         return entity.a.getPlayer();
     }
     
-    public Player matchPlayer(String wantedPlayerName) {
-        Player wantedPlayer = null;
-     
+    public List<Player> matchPlayer(String partialName) {
+        List<Player> matchedPlayers = new ArrayList<Player>();
+        
         for (Player iterPlayer : this.getOnlinePlayers()) {
             String iterPlayerName = iterPlayer.getName();
 
-            if (wantedPlayerName.equalsIgnoreCase(iterPlayerName)) {
+            if (partialName.equalsIgnoreCase(iterPlayerName)) {
                 // Exact match
-                wantedPlayer = this.getPlayer(wantedPlayerName);
-                break;
-            }
-            if (wantedPlayerName.toLowerCase().indexOf(iterPlayerName.toLowerCase()) != -1) {
-                // Partial match
-                if (wantedPlayer != null) {
-                    // Multiple matches
-                    return null;
-                }
-                wantedPlayer = iterPlayer;
+            	matchedPlayers.add(iterPlayer);
+            	break;
+            }	
+            if (iterPlayerName.toLowerCase().indexOf(partialName.toLowerCase()) != -1) {
+            	// Partial match
+                matchedPlayers.add(iterPlayer);
             }
         }
 
-        return wantedPlayer;
+        return matchedPlayers;
     }
 
     public PluginManager getPluginManager() {

From 493854977711f2834ac861bc36c8218f2010b7d5 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 10:43:51 +0000
Subject: [PATCH 05/27] Added block.getFace(Block) and block.getFace(BlockFace,
 int)

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../org/bukkit/craftbukkit/CraftBlock.java    | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
index 19dce3c70e..4048434a38 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
@@ -156,6 +156,26 @@ public class CraftBlock implements Block {
         return getRelative(face.getModX(), face.getModY(), face.getModZ());
     }
 
+    /**
+     * Gets the block at the given distance of the given face<br />
+     * <br />
+     * For example, the following method places water at 100,102,100; two blocks
+     * above 100,100,100.
+     * <pre>
+     * Block block = world.getBlockAt(100,100,100);
+     * Block shower = block.getFace(BlockFace.Up, 2);
+     * shower.setType(Material.WATER);
+     * </pre>
+     *
+     * @param face Face of this block to return
+     * @param distance Distance to get the block at
+     * @return Block at the given face
+     */
+    public Block getFace(final BlockFace face, final int distance) {
+        return getRelative(face.getModX() * distance, face.getModY() * distance,
+                face.getModZ() * distance);
+    }
+
     /**
      * Gets the block at the given offsets
      *
@@ -168,6 +188,38 @@ public class CraftBlock implements Block {
         return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ);
     }
 
+    /**
+     * Gets the face relation of this block compared to the given block<br />
+     * <br />
+     * For example:
+     * <pre>
+     * Block current = world.getBlockAt(100, 100, 100);
+     * Block target = world.getBlockAt(100, 101, 100);
+     *
+     * current.getFace(target) == BlockFace.Up;
+     * </pre>
+     * <br />
+     * If the given block is not connected to this block, null may be returned
+     *
+     * @param block Block to compare against this block
+     * @return BlockFace of this block which has the requested block, or null
+     */
+    public BlockFace getFace(final Block block) {
+        BlockFace[] values = BlockFace.values();
+
+        for (BlockFace face : values) {
+            if (
+                    (this.getX() + face.getModX() == block.getX()) &&
+                    (this.getY() + face.getModY() == block.getY()) &&
+                    (this.getZ() + face.getModZ() == block.getZ())
+                ) {
+                return face;
+            }
+        }
+
+        return null;
+    }
+
     @Override
     public String toString() {
         return "CraftBlock{" + "world=" + world + "x=" + x + "y=" + y + "z=" + z + "type=" + type + "data=" + data + '}';

From 4cd2b9af938839d86cf92f17e7d824ab5be037a3 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 10:48:09 +0000
Subject: [PATCH 06/27] Block.getFace(BlockFace) is an override for
 Block.getFace(BlockFace, int)

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftBlock.java        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
index 4048434a38..e706951e6f 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
@@ -153,7 +153,7 @@ public class CraftBlock implements Block {
      * @return Block at the given face
      */
     public Block getFace(final BlockFace face) {
-        return getRelative(face.getModX(), face.getModY(), face.getModZ());
+        return getFace(face, 1);
     }
 
     /**

From d7d4579cf4179bebf4cc31cac1aec866a99cfcff Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 13:27:26 +0000
Subject: [PATCH 07/27] Implemented Player.getDisplayName/setDisplayName

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../main/java/org/bukkit/craftbukkit/CraftPlayer.java | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java
index 7fc7ace765..406e127a6d 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java
@@ -7,11 +7,12 @@ import org.bukkit.Location;
 import org.bukkit.Player;
 
 public class CraftPlayer extends CraftHumanEntity implements Player {
-
     private EntityPlayerMP entity;
+    private String name;
 
     public CraftPlayer(CraftServer server, EntityPlayerMP entity) {
         super(server, entity);
+        this.name = getName();
         this.entity = entity;
     }
 
@@ -47,6 +48,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
         entity.a.a(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
     }
 
+    public String getDisplayName() {
+        return name;
+    }
+
+    public void getDisplayName(final String name) {
+        this.name = name;
+    }
+
     @Override
     public String toString() {
         return "CraftPlayer{" + "name=" + getName() + '}';

From 0e4e6c21e544be4a8c21d7bfda48ac5dbbc05123 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 13:28:23 +0000
Subject: [PATCH 08/27] Player display name is shown in chat

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftPlayer.java       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java
index 406e127a6d..e3b093d221 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftPlayer.java
@@ -52,7 +52,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
         return name;
     }
 
-    public void getDisplayName(final String name) {
+    public void setDisplayName(final String name) {
         this.name = name;
     }
 

From 08343616c618569df509f1c6c8a47f7862908666 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 00:08:30 +0800
Subject: [PATCH 09/27] Make matchPlayer return only the exact-matched player,
 if there is one.

By: Animosity <nullcline@gmail.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftServer.java        | 1 +
 1 file changed, 1 insertion(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 2d0d0c96eb..c3b9c7cdab 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -90,6 +90,7 @@ public final class CraftServer implements Server {
 
             if (partialName.equalsIgnoreCase(iterPlayerName)) {
                 // Exact match
+            	matchedPlayers.clear();
             	matchedPlayers.add(iterPlayer);
             	break;
             }	

From dc8649f340e16c58168178f12bc8b4ad9c638eaa Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 16:26:06 +0000
Subject: [PATCH 10/27] Implemented CraftBlockState

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../org/bukkit/craftbukkit/CraftBlock.java    |   6 +
 .../craftbukkit/block/CraftBlockState.java    | 146 ++++++++++++++++++
 2 files changed, 152 insertions(+)
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
index e706951e6f..204a25ebb9 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
@@ -2,6 +2,8 @@
 package org.bukkit.craftbukkit;
 
 import org.bukkit.*;
+import org.bukkit.block.BlockState;
+import org.bukkit.craftbukkit.block.CraftBlockState;
 
 public class CraftBlock implements Block {
     private final CraftWorld world;
@@ -249,4 +251,8 @@ public class CraftBlock implements Block {
             return BlockFace.Self;
         }
     }
+
+    public BlockState getState() {
+        return new CraftBlockState(world, x, y, z, type, data);
+    }
 }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
new file mode 100644
index 0000000000..b5320468c5
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -0,0 +1,146 @@
+
+package org.bukkit.craftbukkit.block;
+
+import org.bukkit.Block;
+import org.bukkit.Chunk;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.BlockState;
+import org.bukkit.craftbukkit.CraftChunk;
+import org.bukkit.craftbukkit.CraftWorld;
+
+public class CraftBlockState implements BlockState {
+    private final CraftWorld world;
+    private final CraftChunk chunk;
+    private final int x;
+    private final int y;
+    private final int z;
+    protected int type;
+    protected byte data;
+    protected byte light;
+
+    public CraftBlockState(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
+        this.world = world;
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.type = type;
+        this.data = data;
+        this.light = (byte)world.getHandle().i(x, y, z);
+        this.chunk = (CraftChunk)world.getChunkAt(x << 4, z << 4);
+    }
+
+    /**
+     * Gets the world which contains this Block
+     *
+     * @return World containing this block
+     */
+    public World getWorld() {
+        return world;
+    }
+
+    /**
+     * Gets the x-coordinate of this block
+     *
+     * @return x-coordinate
+     */
+    public int getX() {
+        return x;
+    }
+
+    /**
+     * Gets the y-coordinate of this block
+     *
+     * @return y-coordinate
+     */
+    public int getY() {
+        return y;
+    }
+
+    /**
+     * Gets the z-coordinate of this block
+     *
+     * @return z-coordinate
+     */
+    public int getZ() {
+        return z;
+    }
+
+    /**
+     * Gets the chunk which contains this block
+     *
+     * @return Containing Chunk
+     */
+    public Chunk getChunk() {
+        return chunk;
+    }
+
+    /**
+     * Sets the metadata for this block
+     *
+     * @param data New block specific metadata
+     */
+    public void setData(final byte data) {
+        this.data = data;
+        world.getHandle().c(x, y, z, data);
+    }
+
+    /**
+     * Gets the metadata for this block
+     *
+     * @return block specific metadata
+     */
+    public byte getData() {
+        return data;
+    }
+
+    /**
+     * Sets the type of this block
+     *
+     * @param type Material to change this block to
+     */
+    public void setType(final Material type) {
+        setTypeID(type.getID());
+    }
+
+    /**
+     * Sets the type-ID of this block
+     *
+     * @param type Type-ID to change this block to
+     */
+    public void setTypeID(final int type) {
+        this.type = type;
+        world.getHandle().d(x, y, z, type);
+    }
+
+    /**
+     * Gets the type of this block
+     *
+     * @return block type
+     */
+    public Material getType() {
+        return Material.getMaterial(getTypeID());
+    }
+
+    /**
+     * Gets the type-ID of this block
+     *
+     * @return block type-ID
+     */
+    public int getTypeID() {
+        return type;
+    }
+
+    /**
+     * Gets the light level between 0-15
+     *
+     * @return light level
+     */
+    public byte getLightLevel() {
+        return light;
+    }
+
+    public Block getBlock() {
+        return world.getBlockAt(x, y, z);
+    }
+}

From 1c5ef4139d6f484dea0ba99d6e9b9847cb03e1be Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 16:53:16 +0000
Subject: [PATCH 11/27] Start of update() + added sign

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../craftbukkit/block/CraftBlockState.java    | 16 +++++++++++
 .../bukkit/craftbukkit/block/CraftSign.java   | 27 +++++++++++++++++++
 2 files changed, 43 insertions(+)
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
index b5320468c5..0b216be149 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -143,4 +143,20 @@ public class CraftBlockState implements BlockState {
     public Block getBlock() {
         return world.getBlockAt(x, y, z);
     }
+
+    public boolean update() {
+        return update(false);
+    }
+
+    public boolean update(boolean force) { // TODO
+        Block block = getBlock();
+
+        synchronized (block) {
+            if (block.getType() != this.getType()) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
new file mode 100644
index 0000000000..ec606a7572
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
@@ -0,0 +1,27 @@
+
+package org.bukkit.craftbukkit.block;
+
+import org.bukkit.Block;
+import org.bukkit.Chunk;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Sign;
+import org.bukkit.craftbukkit.CraftWorld;
+
+public class CraftSign extends CraftBlockState implements Sign {
+    public CraftSign(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
+        super(world, x, y, z, type, data);
+    }
+
+    public String[] getLines() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public String getLine(int index) throws IndexOutOfBoundsException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void setLine(int index, String line) throws IndexOutOfBoundsException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}

From 6dae74f72108ffe1518128f9f83b5b340cccac7e Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 12:00:08 -0800
Subject: [PATCH 12/27] Implemented LivingEntity.shootArrow().

By: sk89q <the.sk89q@gmail.com>
---
 .../java/org/bukkit/craftbukkit/CraftLivingEntity.java | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java
index 369314deea..50a297f618 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java
@@ -2,10 +2,12 @@
 package org.bukkit.craftbukkit;
 
 import net.minecraft.server.Entity;
+import net.minecraft.server.EntityArrow;
 import net.minecraft.server.EntityEgg;
 import net.minecraft.server.EntityLiving;
 import net.minecraft.server.EntitySnowball;
 
+import org.bukkit.Arrow;
 import org.bukkit.Egg;
 import org.bukkit.LivingEntity;
 import org.bukkit.Snowball;
@@ -58,4 +60,12 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
         world.a(snowball);
         return new CraftSnowball(server, snowball);
     }
+
+    @Override
+    public Arrow shootArrow() {
+        net.minecraft.server.World world = ((CraftWorld)getWorld()).getHandle();
+        EntityArrow snowball = new EntityArrow(world, entity);
+        world.a(snowball);
+        return new CraftArrow(server, snowball);
+    }
 }

From 74629b6c5f82023deb1900a29bf84350ae3c1e62 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 12:00:44 -0800
Subject: [PATCH 13/27] Added World.toCraftEntity() to convert Minecraft
 entities to CraftBukkit entities.

By: sk89q <the.sk89q@gmail.com>
---
 .../org/bukkit/craftbukkit/CraftWorld.java    | 34 ++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 74c49a9ec1..b236c2ca67 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -6,9 +6,15 @@ import java.util.Map;
 
 import net.minecraft.server.EntityMinecart;
 import java.util.Random;
+
+import net.minecraft.server.EntityEgg;
+import net.minecraft.server.EntityLiving;
+import net.minecraft.server.EntityPlayerMP;
+import net.minecraft.server.EntitySnowball;
+import net.minecraft.server.EntityArrow;
+import net.minecraft.server.EntityPlayer;
 import net.minecraft.server.WorldGenBigTree;
 import net.minecraft.server.WorldServer;
-import net.minecraft.server.EntityArrow;
 import net.minecraft.server.WorldGenTrees;
 import org.bukkit.Arrow;
 import org.bukkit.Block;
@@ -149,6 +155,32 @@ public class CraftWorld implements World {
         return treeGen.a(world, rand,
                 loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
     }
+    
+    public CraftEntity toCraftEntity(net.minecraft.server.Entity entity) {
+        if (entity instanceof EntityArrow) {
+            return new CraftArrow(world.getServer(), (EntityArrow)entity);
+        } else if (entity instanceof EntityEgg) {
+            return new CraftEgg(world.getServer(), (EntityEgg)entity);
+        } else if (entity instanceof EntityPlayerMP) {
+            return new CraftPlayer(world.getServer(), (EntityPlayerMP)entity);
+        } else if (entity instanceof EntitySnowball) {
+            return new CraftSnowball(world.getServer(), (EntitySnowball)entity);
+        } else if (entity instanceof EntityMinecart) {
+            EntityMinecart minecart = (EntityMinecart)entity;
+            if (minecart.minecart != null) {
+                return minecart.minecart;
+            }
+            
+            return CraftMinecart.getCraftMinecart(world.getServer(),
+                    (EntityMinecart)entity);
+        } else if (entity instanceof EntityPlayer) {
+            return new CraftHumanEntity(world.getServer(), (EntityPlayer)entity);
+        } else if (entity instanceof EntityLiving) {
+            return new CraftLivingEntity(world.getServer(), (EntityLiving)entity);
+        } else {
+            return null;
+        }
+    }
 
     @Override
     public String toString() {

From e44031b5c4ad12b13f5a3635161141b2c2185b41 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 12:01:37 -0800
Subject: [PATCH 14/27] Updated Minecart/vehicle Bukkit implementation.

By: sk89q <the.sk89q@gmail.com>
---
 .../java/org/bukkit/craftbukkit/CraftMinecart.java  |  9 ---------
 .../java/org/bukkit/craftbukkit/CraftVehicle.java   | 13 ++++++++++---
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java
index 44082603ba..583f7dbd17 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java
@@ -48,15 +48,6 @@ public class CraftMinecart extends CraftVehicle implements Minecart {
         minecart.u = vel.getZ();
     }
 
-    public LivingEntity getPassenger() {
-        // @TODO: Implement
-        return null;
-    }
-
-    public boolean isEmpty() {
-        return minecart.j == null;
-    }
-
     public void setDamage(int damage) {
         minecart.a = damage;
     }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
index a5c03868c4..c978b8b7df 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
@@ -1,7 +1,6 @@
 package org.bukkit.craftbukkit;
 
-import net.minecraft.server.Entity;
-
+import org.bukkit.Entity;
 import org.bukkit.Vehicle;
 
 /**
@@ -10,7 +9,15 @@ import org.bukkit.Vehicle;
  * @author sk89q
  */
 public abstract class CraftVehicle extends CraftEntity implements Vehicle {
-    public CraftVehicle(CraftServer server, Entity entity) {
+    public CraftVehicle(CraftServer server, net.minecraft.server.Entity entity) {
         super(server, entity);
     }
+
+    public Entity getPassenger() {
+        return ((CraftWorld)getWorld()).toCraftEntity(getHandle().j);
+    }
+
+    public boolean isEmpty() {
+        return getHandle().j == null;
+    }
 }

From 76d5da14fd0679f3a6b2c4d197241d427512316a Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 13:05:25 -0800
Subject: [PATCH 15/27] Implemented boat, fixed some event issues with
 minecarts, and implemented the events for boats that were implemented for
 minecarts.

By: sk89q <the.sk89q@gmail.com>
---
 .../java/org/bukkit/craftbukkit/CraftBoat.java | 18 ++++++++++++++++++
 .../org/bukkit/craftbukkit/CraftMinecart.java  | 12 ------------
 .../org/bukkit/craftbukkit/CraftVehicle.java   | 14 ++++++++++++++
 3 files changed, 32 insertions(+), 12 deletions(-)
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java
new file mode 100644
index 0000000000..dd3acb62df
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java
@@ -0,0 +1,18 @@
+package org.bukkit.craftbukkit;
+
+import net.minecraft.server.EntityBoat;
+import org.bukkit.Boat;
+
+/**
+ * A minecart.
+ * 
+ * @author sk89q
+ */
+public class CraftBoat extends CraftVehicle implements Boat {
+    protected EntityBoat boat;
+
+    public CraftBoat(CraftServer server, EntityBoat entity) {
+        super(server, entity);
+        boat = entity;
+    }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java
index 583f7dbd17..0d55ad8219 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMinecart.java
@@ -1,9 +1,7 @@
 package org.bukkit.craftbukkit;
 
 import net.minecraft.server.EntityMinecart;
-import org.bukkit.LivingEntity;
 import org.bukkit.Minecart;
-import org.bukkit.Vector;
 
 /**
  * A minecart.
@@ -38,16 +36,6 @@ public class CraftMinecart extends CraftVehicle implements Minecart {
         minecart = entity;
     }
 
-    public Vector getVelocity() {
-        return new Vector(minecart.s, minecart.t, minecart.u);
-    }
-
-    public void setVelocity(Vector vel) {
-        minecart.s = vel.getX();
-        minecart.t = vel.getY();
-        minecart.u = vel.getZ();
-    }
-
     public void setDamage(int damage) {
         minecart.a = damage;
     }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
index c978b8b7df..42671c13b2 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
@@ -1,6 +1,7 @@
 package org.bukkit.craftbukkit;
 
 import org.bukkit.Entity;
+import org.bukkit.Vector;
 import org.bukkit.Vehicle;
 
 /**
@@ -9,8 +10,11 @@ import org.bukkit.Vehicle;
  * @author sk89q
  */
 public abstract class CraftVehicle extends CraftEntity implements Vehicle {
+    private net.minecraft.server.Entity vehicle;
+    
     public CraftVehicle(CraftServer server, net.minecraft.server.Entity entity) {
         super(server, entity);
+        vehicle = entity;
     }
 
     public Entity getPassenger() {
@@ -20,4 +24,14 @@ public abstract class CraftVehicle extends CraftEntity implements Vehicle {
     public boolean isEmpty() {
         return getHandle().j == null;
     }
+
+    public Vector getVelocity() {
+        return new Vector(vehicle.s, vehicle.t, vehicle.u);
+    }
+
+    public void setVelocity(Vector vel) {
+        vehicle.s = vel.getX();
+        vehicle.t = vel.getY();
+        vehicle.u = vel.getZ();
+    }
 }

From 4db1faa590da5b7f65798155da78f501dabcdb79 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 13:40:16 -0800
Subject: [PATCH 16/27] Moved CraftVehicle.*Velocity() to CraftEntity as
 velocity is a component of all entities.

By: sk89q <the.sk89q@gmail.com>
---
 .../java/org/bukkit/craftbukkit/CraftEntity.java    | 11 +++++++++++
 .../java/org/bukkit/craftbukkit/CraftVehicle.java   | 13 -------------
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
index 11e5847e31..535db3905b 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
@@ -4,6 +4,7 @@ package org.bukkit.craftbukkit;
 import net.minecraft.server.Entity;
 import net.minecraft.server.WorldServer;
 import org.bukkit.Location;
+import org.bukkit.Vector;
 import org.bukkit.World;
 
 public abstract class CraftEntity implements org.bukkit.Entity {
@@ -19,6 +20,16 @@ public abstract class CraftEntity implements org.bukkit.Entity {
         return new Location(getWorld(), entity.p, entity.q, entity.r, entity.v, entity.w);
     }
 
+    public Vector getVelocity() {
+        return new Vector(entity.s, entity.t, entity.u);
+    }
+
+    public void setVelocity(Vector vel) {
+        entity.s = vel.getX();
+        entity.t = vel.getY();
+        entity.u = vel.getZ();
+    }
+
     public World getWorld() {
         return ((WorldServer)entity.l).getWorld();
     }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
index 42671c13b2..3ffed5014b 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
@@ -10,11 +10,8 @@ import org.bukkit.Vehicle;
  * @author sk89q
  */
 public abstract class CraftVehicle extends CraftEntity implements Vehicle {
-    private net.minecraft.server.Entity vehicle;
-    
     public CraftVehicle(CraftServer server, net.minecraft.server.Entity entity) {
         super(server, entity);
-        vehicle = entity;
     }
 
     public Entity getPassenger() {
@@ -24,14 +21,4 @@ public abstract class CraftVehicle extends CraftEntity implements Vehicle {
     public boolean isEmpty() {
         return getHandle().j == null;
     }
-
-    public Vector getVelocity() {
-        return new Vector(vehicle.s, vehicle.t, vehicle.u);
-    }
-
-    public void setVelocity(Vector vel) {
-        vehicle.s = vel.getX();
-        vehicle.t = vel.getY();
-        vehicle.u = vel.getZ();
-    }
 }

From 79b394a91403149ef0dd2c92e4189d20e343900a Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 14:01:37 -0800
Subject: [PATCH 17/27] Implemented World.spawnBoat(), added CraftMappable
 interface that defines a method to get an org.bukkit.craftbukkit.CraftEntity
 from implementing net.minecart.server.Entity entities, changed
 CraftWorld.toCraftEntity() to use this new interface for boats and minecarts.

By: sk89q <the.sk89q@gmail.com>
---
 .../org/bukkit/craftbukkit/CraftMappable.java | 16 ++++++++++++++++
 .../org/bukkit/craftbukkit/CraftWorld.java    | 19 +++++++++++--------
 2 files changed, 27 insertions(+), 8 deletions(-)
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java
new file mode 100644
index 0000000000..9bcc4b9936
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java
@@ -0,0 +1,16 @@
+package org.bukkit.craftbukkit;
+
+/**
+ * Indicates that an object has a method to get its CraftBukkit-equivalent
+ * CraftEntity object from its Minecraft net.minecraft.server.Entity object.
+ * 
+ * @author sk89q
+ */
+public interface CraftMappable {
+    /**
+     * Gets the CraftEntity version.
+     * 
+     * @return
+     */
+    public CraftEntity getCraftEntity();
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index b236c2ca67..fb6d67f6ff 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -7,6 +7,7 @@ import java.util.Map;
 import net.minecraft.server.EntityMinecart;
 import java.util.Random;
 
+import net.minecraft.server.EntityBoat;
 import net.minecraft.server.EntityEgg;
 import net.minecraft.server.EntityLiving;
 import net.minecraft.server.EntityPlayerMP;
@@ -18,6 +19,7 @@ import net.minecraft.server.WorldServer;
 import net.minecraft.server.WorldGenTrees;
 import org.bukkit.Arrow;
 import org.bukkit.Block;
+import org.bukkit.Boat;
 import org.bukkit.Chunk;
 import org.bukkit.Location;
 import org.bukkit.Minecart;
@@ -144,6 +146,13 @@ public class CraftWorld implements World {
         return new CraftPoweredMinecart(world.getServer(), minecart);
     }
     
+    public Boat spawnBoat(Location loc) {
+        EntityBoat boat =
+            new EntityBoat(world, loc.getX(), loc.getY(), loc.getZ());
+        world.a(boat);
+        return new CraftBoat(world.getServer(), boat);
+    }
+    
     public boolean generateTree(Location loc) {
         WorldGenTrees treeGen = new WorldGenTrees();
         return treeGen.a(world, rand,
@@ -165,18 +174,12 @@ public class CraftWorld implements World {
             return new CraftPlayer(world.getServer(), (EntityPlayerMP)entity);
         } else if (entity instanceof EntitySnowball) {
             return new CraftSnowball(world.getServer(), (EntitySnowball)entity);
-        } else if (entity instanceof EntityMinecart) {
-            EntityMinecart minecart = (EntityMinecart)entity;
-            if (minecart.minecart != null) {
-                return minecart.minecart;
-            }
-            
-            return CraftMinecart.getCraftMinecart(world.getServer(),
-                    (EntityMinecart)entity);
         } else if (entity instanceof EntityPlayer) {
             return new CraftHumanEntity(world.getServer(), (EntityPlayer)entity);
         } else if (entity instanceof EntityLiving) {
             return new CraftLivingEntity(world.getServer(), (EntityLiving)entity);
+        } else if (entity instanceof CraftMappable) {
+            return ((CraftMappable)entity).getCraftEntity();
         } else {
             return null;
         }

From a4aca48cb4fc7e1ec64003cdb99590be36845f30 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 14:06:08 -0800
Subject: [PATCH 18/27] Changed resolution order in CraftWorld.toCraftEntity()
 to give CraftMappable precedence.

By: sk89q <the.sk89q@gmail.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftWorld.java    | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index fb6d67f6ff..fdfcaea5d3 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -166,7 +166,9 @@ public class CraftWorld implements World {
     }
     
     public CraftEntity toCraftEntity(net.minecraft.server.Entity entity) {
-        if (entity instanceof EntityArrow) {
+        if (entity instanceof CraftMappable) {
+            return ((CraftMappable)entity).getCraftEntity();
+        } else if (entity instanceof EntityArrow) {
             return new CraftArrow(world.getServer(), (EntityArrow)entity);
         } else if (entity instanceof EntityEgg) {
             return new CraftEgg(world.getServer(), (EntityEgg)entity);
@@ -178,8 +180,6 @@ public class CraftWorld implements World {
             return new CraftHumanEntity(world.getServer(), (EntityPlayer)entity);
         } else if (entity instanceof EntityLiving) {
             return new CraftLivingEntity(world.getServer(), (EntityLiving)entity);
-        } else if (entity instanceof CraftMappable) {
-            return ((CraftMappable)entity).getCraftEntity();
         } else {
             return null;
         }

From b0bf52751f2bb2e62735884aed44d5b8bd987be5 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Fri, 7 Jan 2011 16:26:08 -0800
Subject: [PATCH 19/27] Added passenger methods to Vehicle/LivingEntity.

By: sk89q <the.sk89q@gmail.com>
---
 .../org/bukkit/craftbukkit/CraftEntity.java   |  1 +
 .../bukkit/craftbukkit/CraftLivingEntity.java | 28 ++++++++++++++++++-
 .../org/bukkit/craftbukkit/CraftVehicle.java  | 14 ++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
index 535db3905b..909bfae89c 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
@@ -5,6 +5,7 @@ import net.minecraft.server.Entity;
 import net.minecraft.server.WorldServer;
 import org.bukkit.Location;
 import org.bukkit.Vector;
+import org.bukkit.Vehicle;
 import org.bukkit.World;
 
 public abstract class CraftEntity implements org.bukkit.Entity {
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java
index 50a297f618..449ea62fe8 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLivingEntity.java
@@ -11,6 +11,7 @@ import org.bukkit.Arrow;
 import org.bukkit.Egg;
 import org.bukkit.LivingEntity;
 import org.bukkit.Snowball;
+import org.bukkit.Vehicle;
 
 public class CraftLivingEntity extends CraftEntity implements LivingEntity {
     private EntityLiving entity;
@@ -61,11 +62,36 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
         return new CraftSnowball(server, snowball);
     }
 
-    @Override
     public Arrow shootArrow() {
         net.minecraft.server.World world = ((CraftWorld)getWorld()).getHandle();
         EntityArrow snowball = new EntityArrow(world, entity);
         world.a(snowball);
         return new CraftArrow(server, snowball);
     }
+
+    public boolean isInsideVehicle() {
+        return entity.k != null;
+    }
+
+    public boolean leaveVehicle() {
+        if (entity.k == null) {
+            return false;
+        }
+        
+        entity.setPassengerOf(null);
+        return true;
+    }
+
+    public Vehicle getVehicle() {
+        if (entity.k == null) {
+            return null;
+        }
+        
+        org.bukkit.Entity vehicle = ((CraftWorld)getWorld()).toCraftEntity(entity.k);
+        if (vehicle instanceof Vehicle) {
+            return (Vehicle)vehicle;
+        }
+        
+        return null;
+    }
 }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
index 3ffed5014b..ffc93da19b 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftVehicle.java
@@ -17,8 +17,22 @@ public abstract class CraftVehicle extends CraftEntity implements Vehicle {
     public Entity getPassenger() {
         return ((CraftWorld)getWorld()).toCraftEntity(getHandle().j);
     }
+    
+    public boolean setPassenger(Entity passenger) {
+        ((CraftEntity)passenger).getHandle().setPassengerOf(getHandle());
+        return true;
+    }
 
     public boolean isEmpty() {
         return getHandle().j == null;
     }
+    
+    public boolean eject() {
+        if (getHandle().j == null) {
+            return false;
+        }
+        
+        getHandle().j.setPassengerOf(null);
+        return true;
+    }
 }

From 31546ddf8e77e538c19ceb0750cced1abba5b5fb Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 01:22:17 +0000
Subject: [PATCH 20/27] Implemented BlockState.update(boolean), signs should
 now work, cleaned up some code a little

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../org/bukkit/craftbukkit/CraftBlock.java    | 12 ++++++-
 .../org/bukkit/craftbukkit/CraftBoat.java     | 36 +++++++++----------
 .../org/bukkit/craftbukkit/CraftMappable.java | 32 ++++++++---------
 .../org/bukkit/craftbukkit/CraftWorld.java    |  5 +++
 .../craftbukkit/block/CraftBlockState.java    | 26 ++++++++------
 .../bukkit/craftbukkit/block/CraftSign.java   | 31 +++++++++++-----
 6 files changed, 89 insertions(+), 53 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
index 204a25ebb9..1650e972b6 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
@@ -4,6 +4,7 @@ package org.bukkit.craftbukkit;
 import org.bukkit.*;
 import org.bukkit.block.BlockState;
 import org.bukkit.craftbukkit.block.CraftBlockState;
+import org.bukkit.craftbukkit.block.CraftSign;
 
 public class CraftBlock implements Block {
     private final CraftWorld world;
@@ -253,6 +254,15 @@ public class CraftBlock implements Block {
     }
 
     public BlockState getState() {
-        return new CraftBlockState(world, x, y, z, type, data);
+        Material material = getType();
+
+        switch (material) {
+            case Sign:
+            case SignPost:
+            case WallSign:
+                return new CraftSign(this);
+            default:
+                return new CraftBlockState(this);
+        }
     }
 }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java
index dd3acb62df..cad1e40779 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBoat.java
@@ -1,18 +1,18 @@
-package org.bukkit.craftbukkit;
-
-import net.minecraft.server.EntityBoat;
-import org.bukkit.Boat;
-
-/**
- * A minecart.
- * 
- * @author sk89q
- */
-public class CraftBoat extends CraftVehicle implements Boat {
-    protected EntityBoat boat;
-
-    public CraftBoat(CraftServer server, EntityBoat entity) {
-        super(server, entity);
-        boat = entity;
-    }
-}
+package org.bukkit.craftbukkit;
+
+import net.minecraft.server.EntityBoat;
+import org.bukkit.Boat;
+
+/**
+ * A minecart.
+ * 
+ * @author sk89q
+ */
+public class CraftBoat extends CraftVehicle implements Boat {
+    protected EntityBoat boat;
+
+    public CraftBoat(CraftServer server, EntityBoat entity) {
+        super(server, entity);
+        boat = entity;
+    }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java
index 9bcc4b9936..8e411846bd 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMappable.java
@@ -1,16 +1,16 @@
-package org.bukkit.craftbukkit;
-
-/**
- * Indicates that an object has a method to get its CraftBukkit-equivalent
- * CraftEntity object from its Minecraft net.minecraft.server.Entity object.
- * 
- * @author sk89q
- */
-public interface CraftMappable {
-    /**
-     * Gets the CraftEntity version.
-     * 
-     * @return
-     */
-    public CraftEntity getCraftEntity();
-}
+package org.bukkit.craftbukkit;
+
+/**
+ * Indicates that an object has a method to get its CraftBukkit-equivalent
+ * CraftEntity object from its Minecraft net.minecraft.server.Entity object.
+ * 
+ * @author sk89q
+ */
+public interface CraftMappable {
+    /**
+     * Gets the CraftEntity version.
+     * 
+     * @return
+     */
+    public CraftEntity getCraftEntity();
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index fdfcaea5d3..3631d13294 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -14,6 +14,7 @@ import net.minecraft.server.EntityPlayerMP;
 import net.minecraft.server.EntitySnowball;
 import net.minecraft.server.EntityArrow;
 import net.minecraft.server.EntityPlayer;
+import net.minecraft.server.TileEntity;
 import net.minecraft.server.WorldGenBigTree;
 import net.minecraft.server.WorldServer;
 import net.minecraft.server.WorldGenTrees;
@@ -185,6 +186,10 @@ public class CraftWorld implements World {
         }
     }
 
+    public TileEntity getTileEntityAt(final int x, final int y, final int z) {
+        return world.l(x, y, z);
+    }
+
     @Override
     public String toString() {
         return "CraftWorld";
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
index 0b216be149..f2a0c2756d 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java
@@ -19,15 +19,15 @@ public class CraftBlockState implements BlockState {
     protected byte data;
     protected byte light;
 
-    public CraftBlockState(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
-        this.world = world;
-        this.x = x;
-        this.y = y;
-        this.z = z;
-        this.type = type;
-        this.data = data;
-        this.light = (byte)world.getHandle().i(x, y, z);
-        this.chunk = (CraftChunk)world.getChunkAt(x << 4, z << 4);
+    public CraftBlockState(final Block block) {
+        this.world = (CraftWorld)block.getWorld();
+        this.x = block.getX();
+        this.y = block.getY();
+        this.z = block.getZ();
+        this.type = block.getTypeID();
+        this.data = block.getData();
+        this.light = block.getLightLevel();
+        this.chunk = (CraftChunk)block.getChunk();
     }
 
     /**
@@ -153,8 +153,14 @@ public class CraftBlockState implements BlockState {
 
         synchronized (block) {
             if (block.getType() != this.getType()) {
-                return false;
+                if (force) {
+                    block.setTypeID(this.getTypeID());
+                } else {
+                    return false;
+                }
             }
+
+            block.setData(data);
         }
 
         return true;
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
index ec606a7572..a3a8649b93 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
@@ -1,27 +1,42 @@
 
 package org.bukkit.craftbukkit.block;
 
+import net.minecraft.server.TileEntitySign;
 import org.bukkit.Block;
-import org.bukkit.Chunk;
-import org.bukkit.Material;
-import org.bukkit.World;
 import org.bukkit.block.Sign;
 import org.bukkit.craftbukkit.CraftWorld;
 
 public class CraftSign extends CraftBlockState implements Sign {
-    public CraftSign(final CraftWorld world, final int x, final int y, final int z, final int type, final byte data) {
-        super(world, x, y, z, type, data);
+    private final CraftWorld world;
+    private final TileEntitySign sign;
+
+    public CraftSign(final Block block) {
+        super(block);
+
+        world = (CraftWorld)block.getWorld();
+        sign = (TileEntitySign)world.getTileEntityAt(getX(), getY(), getZ());
     }
 
     public String[] getLines() {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return sign.e;
     }
 
     public String getLine(int index) throws IndexOutOfBoundsException {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return sign.e[index];
     }
 
     public void setLine(int index, String line) throws IndexOutOfBoundsException {
-        throw new UnsupportedOperationException("Not supported yet.");
+        sign.e[index] = line;
+    }
+
+    @Override
+    public boolean update(boolean force) {
+        boolean result = super.update(force);
+
+        if (result) {
+            sign.d();
+        }
+
+        return result;
     }
 }

From ee4573d9d17136df2494f918bcf11b456bbb9fa0 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 02:20:11 +0000
Subject: [PATCH 21/27] Added Entity.teleportTo(Entity)

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftEntity.java     | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
index 909bfae89c..d9ac3190e9 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftEntity.java
@@ -39,6 +39,10 @@ public abstract class CraftEntity implements org.bukkit.Entity {
         entity.b(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
     }
 
+    public void teleportTo(org.bukkit.Entity destination) {
+        teleportTo(destination.getLocation());
+    }
+
     public int getEntityID() {
         return entity.g;
     }

From a5f424708dd76bce35cb1b0af28a34dceae653ed Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 02:29:57 +0000
Subject: [PATCH 22/27] Added World.getName and World.getId

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftWorld.java  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 3631d13294..0edeead30b 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -190,6 +190,14 @@ public class CraftWorld implements World {
         return world.l(x, y, z);
     }
 
+    public String getName() {
+        return world.w;
+    }
+
+    public long getId() {
+        return world.u;
+    }
+
     @Override
     public String toString() {
         return "CraftWorld";

From 79190cff6c8509ba8374dd0ecee0a3df69a1888f Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 03:44:29 +0000
Subject: [PATCH 23/27] Implemented block.getBiome

By: Dinnerbone <dinnerbone@dinnerbone.com>
---
 .../org/bukkit/craftbukkit/CraftBlock.java    | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
index 1650e972b6..92b3ea2e58 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
@@ -1,6 +1,7 @@
 
 package org.bukkit.craftbukkit;
 
+import net.minecraft.server.MobSpawnerBase;
 import org.bukkit.*;
 import org.bukkit.block.BlockState;
 import org.bukkit.craftbukkit.block.CraftBlockState;
@@ -265,4 +266,37 @@ public class CraftBlock implements Block {
                 return new CraftBlockState(this);
         }
     }
+
+    public Biome getBiome() {
+        // TODO: This may not be 100% accurate; investigate into getting per-block instead of per-chunk
+        MobSpawnerBase base = world.getHandle().a().a(chunk.getX(), chunk.getZ());
+
+        if (base == MobSpawnerBase.a) {
+            return Biome.RAINFOREST;
+        } else if (base == MobSpawnerBase.b) {
+            return Biome.SWAMPLAND;
+        } else if (base == MobSpawnerBase.c) {
+            return Biome.SEASONAL_FOREST;
+        } else if (base == MobSpawnerBase.d) {
+            return Biome.FOREST;
+        } else if (base == MobSpawnerBase.e) {
+            return Biome.SAVANNA;
+        } else if (base == MobSpawnerBase.f) {
+            return Biome.SHRUBLAND;
+        } else if (base == MobSpawnerBase.g) {
+            return Biome.TAIGA;
+        } else if (base == MobSpawnerBase.h) {
+            return Biome.DESERT;
+        } else if (base == MobSpawnerBase.i) {
+            return Biome.PLAINS;
+        } else if (base == MobSpawnerBase.j) {
+            return Biome.ICE_DESERT;
+        } else if (base == MobSpawnerBase.k) {
+            return Biome.TUNDRA;
+        } else if (base == MobSpawnerBase.l) {
+            return Biome.HELL;
+        }
+
+        return null;
+    }
 }

From f992249f27b96e6dd4f4e510c4f051cb66ad6c5c Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 12:24:39 -0800
Subject: [PATCH 24/27] Changed Block.setTypeID() to return a boolean
 indicating whether the block was changed (as provided by Minecraft).

By: sk89q <the.sk89q@gmail.com>
---
 .../src/main/java/org/bukkit/craftbukkit/CraftBlock.java     | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
index 92b3ea2e58..64b13a4fe3 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftBlock.java
@@ -117,10 +117,11 @@ public class CraftBlock implements Block {
      * Sets the type-ID of this block
      *
      * @param type Type-ID to change this block to
+     * @return whether the block was changed
      */
-    public void setTypeID(final int type) {
+    public boolean setTypeID(final int type) {
         this.type = type;
-        world.getHandle().d(x, y, z, type);
+        return world.getHandle().d(x, y, z, type);
     }
 
     /**

From 6be602903510364a6c2a3a5b741958ebb5bee42d Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sat, 8 Jan 2011 12:48:45 -0800
Subject: [PATCH 25/27] Implemented item drops.

By: sk89q <the.sk89q@gmail.com>
---
 .../org/bukkit/craftbukkit/CraftItemDrop.java | 23 ++++++++++++++++
 .../org/bukkit/craftbukkit/CraftWorld.java    | 27 +++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemDrop.java

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemDrop.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemDrop.java
new file mode 100644
index 0000000000..0def182530
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemDrop.java
@@ -0,0 +1,23 @@
+package org.bukkit.craftbukkit;
+
+import net.minecraft.server.EntityItem;
+import org.bukkit.ItemDrop;
+import org.bukkit.ItemStack;
+
+/**
+ * Represents an item drop.
+ * 
+ * @author sk89q
+ */
+public class CraftItemDrop extends CraftEntity implements ItemDrop {
+    private EntityItem item;
+    
+    public CraftItemDrop(CraftServer server, EntityItem ent) {
+        super(server, ent);
+        this.item = ent;
+    }
+
+    public ItemStack getItemStack() {
+        return new CraftItemStack(item.a);
+    }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0edeead30b..35f2a3a833 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -9,6 +9,7 @@ import java.util.Random;
 
 import net.minecraft.server.EntityBoat;
 import net.minecraft.server.EntityEgg;
+import net.minecraft.server.EntityItem;
 import net.minecraft.server.EntityLiving;
 import net.minecraft.server.EntityPlayerMP;
 import net.minecraft.server.EntitySnowball;
@@ -22,6 +23,8 @@ import org.bukkit.Arrow;
 import org.bukkit.Block;
 import org.bukkit.Boat;
 import org.bukkit.Chunk;
+import org.bukkit.ItemDrop;
+import org.bukkit.ItemStack;
 import org.bukkit.Location;
 import org.bukkit.Minecart;
 import org.bukkit.PoweredMinecart;
@@ -110,6 +113,28 @@ public class CraftWorld implements World {
     public WorldServer getHandle() {
         return world;
     }
+    
+    public ItemDrop dropItem(Location loc, ItemStack item) {
+        net.minecraft.server.ItemStack stack =
+                new net.minecraft.server.ItemStack(
+                        item.getTypeID(), item.getAmount(), item.getDamage());
+        EntityItem entity = new EntityItem(world, loc.getX(), loc.getY(),
+                loc.getZ(), stack);
+        entity.c = 10;
+        world.a(entity);
+        return new CraftItemDrop(world.getServer(), entity);
+    }
+    
+    public ItemDrop dropItemNaturally(Location loc, ItemStack item) {
+        double xs = world.l.nextFloat() * 0.7F + (1.0F - 0.7F) * 0.5D;
+        double ys = world.l.nextFloat() * 0.7F + (1.0F - 0.7F) * 0.5D;
+        double zs = world.l.nextFloat() * 0.7F + (1.0F - 0.7F) * 0.5D;
+        loc = loc.clone();
+        loc.setX(loc.getX() + xs);
+        loc.setX(loc.getY() + ys);
+        loc.setX(loc.getZ() + zs);
+        return dropItem(loc, item);
+    }
 
     public Arrow spawnArrow(Location loc, Vector velocity, float speed,
             float spread) {
@@ -169,6 +194,8 @@ public class CraftWorld implements World {
     public CraftEntity toCraftEntity(net.minecraft.server.Entity entity) {
         if (entity instanceof CraftMappable) {
             return ((CraftMappable)entity).getCraftEntity();
+        } else if (entity instanceof EntityItem) {
+            return new CraftItemDrop(world.getServer(), (EntityItem)entity);
         } else if (entity instanceof EntityArrow) {
             return new CraftArrow(world.getServer(), (EntityArrow)entity);
         } else if (entity instanceof EntityEgg) {

From 846d1800c59b32cb1170d81d7910ed3996fff3b9 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Mon, 3 Jan 2011 19:32:42 +0100
Subject: [PATCH 26/27] Added compile instructions in README.md

By: Erik Broes <erikbroes@grum.nl>
---
 paper-server/.gitignore |  3 +++
 paper-server/README.md  | 13 +++++++++++++
 2 files changed, 16 insertions(+)
 create mode 100644 paper-server/README.md

diff --git a/paper-server/.gitignore b/paper-server/.gitignore
index 9c0573a55d..9c628f5f76 100644
--- a/paper-server/.gitignore
+++ b/paper-server/.gitignore
@@ -6,6 +6,9 @@
 # netbeans
 /nbproject
 
+# we use maven!
+/build.xml
+
 # maven
 /target
 
diff --git a/paper-server/README.md b/paper-server/README.md
new file mode 100644
index 0000000000..d5719e2ff9
--- /dev/null
+++ b/paper-server/README.md
@@ -0,0 +1,13 @@
+CraftBukkit
+===========
+
+A Bukkit (Minecraft Server API) implementation
+
+Compilation
+-----------
+
+We use maven to handle our dependencies.
+
+* Install [Maven 3](http://maven.apache.org/download.html)
+* Check out and install [Bukkit](http://github.com/Bukkit/Bukkit)
+* Check out this repo and: `mvn clean package`

From 76e05aa578ed14b31a99aa483759b9c73f72045c Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sun, 9 Jan 2011 18:27:46 +0100
Subject: [PATCH 27/27] Added getContents() to IInventory and implemented it.
 Implemented Inventory and PlayerInventory and updated StorageMinecart and
 Slot. Added getMaxStackSize to CraftItemStack.

By: Erik Broes <erikbroes@grum.nl>
---
 .../bukkit/craftbukkit/CraftHumanEntity.java  |  18 +-
 .../bukkit/craftbukkit/CraftInventory.java    | 195 ++++++++++++++++++
 .../craftbukkit/CraftInventoryPlayer.java     |  67 ++++++
 .../bukkit/craftbukkit/CraftItemStack.java    |   6 +-
 .../org/bukkit/craftbukkit/CraftSlot.java     |  25 +++
 .../craftbukkit/CraftStorageMinecart.java     |  33 +--
 6 files changed, 309 insertions(+), 35 deletions(-)
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventory.java
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventoryPlayer.java
 create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/CraftSlot.java

diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java
index b03f096725..91437f4f8c 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftHumanEntity.java
@@ -2,22 +2,18 @@
 package org.bukkit.craftbukkit;
 
 import net.minecraft.server.EntityPlayer;
-import net.minecraft.server.InventoryPlayer;
 import org.bukkit.HumanEntity;
 import org.bukkit.ItemStack;
+import org.bukkit.PlayerInventory;
 
 public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
     private EntityPlayer entity;
+    private CraftInventoryPlayer inventory;
 
     public CraftHumanEntity(final CraftServer server, final EntityPlayer entity) {
         super(server, entity);
         this.entity = entity;
-    }
-
-    public ItemStack getSelectedItem() {
-        // TODO: Implement inventories
-        final InventoryPlayer inventory = entity.an;
-        return new ItemStack(inventory.e().c, inventory.e().a);
+        this.inventory = new CraftInventoryPlayer( entity.an );
     }
 
     public String getName() {
@@ -34,6 +30,14 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
         this.entity = entity;
     }
 
+    public PlayerInventory getInventory() {
+        return inventory;
+    }
+
+    public ItemStack getItemInHand() {
+        return getInventory().getItemInHand();
+    }
+
     @Override
     public String toString() {
         return "CraftHumanEntity{" + "id=" + getEntityID() + "name=" + getName() + '}';
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventory.java
new file mode 100644
index 0000000000..c74ecea373
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventory.java
@@ -0,0 +1,195 @@
+package org.bukkit.craftbukkit;
+
+import java.util.HashMap;
+
+import net.minecraft.server.IInventory;
+
+import org.bukkit.ItemStack;
+import org.bukkit.Material;
+
+public class CraftInventory implements org.bukkit.Inventory {
+    protected IInventory inventory;
+
+    public CraftInventory(IInventory inventory) {
+        this.inventory = inventory;
+    }
+
+    public IInventory getInventory() {
+        return inventory;
+    }
+
+    public int getSize() {
+        return getInventory().a();
+    }
+
+    public String getName() {
+        return getInventory().b();
+    }
+
+    public ItemStack getItem(int index) {
+        return new CraftItemStack(getInventory().a(index));
+    }
+
+    public ItemStack[] getContents() {
+        ItemStack[] items = new ItemStack[getSize()];
+        net.minecraft.server.ItemStack[] mcItems = getInventory().getContents();
+
+        for (int i = 0; i < mcItems.length; i++ ) {
+            items[i] = new CraftItemStack(mcItems[i]);
+        }
+
+        return items;
+    }
+
+    public void setItem(int index, ItemStack item) {
+        getInventory().a( index, new net.minecraft.server.ItemStack( item.getTypeID(), item.getAmount()));
+    }
+
+    public boolean contains(int materialId) {
+        for (ItemStack item: getContents()) {
+            if (item.getTypeID() == materialId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean contains(Material material) {
+        return contains(material.getID());
+    }
+
+    public boolean contains(ItemStack item) {
+        for (ItemStack i: getContents()) {
+            if (item.equals(i)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public HashMap<Integer, ItemStack> all(int materialId) {
+        HashMap<Integer, ItemStack> slots = new HashMap<Integer, ItemStack>();
+
+        ItemStack[] inventory = getContents();
+        for (int i = 0; i < inventory.length; i++) {
+            ItemStack item = inventory[i];
+            if (item.getTypeID() == materialId) {
+                slots.put( i, item );
+            }
+        }
+        return slots;
+    }
+
+    public HashMap<Integer, ItemStack> all(Material material) {
+        return all(material.getID());
+    }
+
+    public HashMap<Integer, ItemStack> all(ItemStack item) {
+        HashMap<Integer, ItemStack> slots = new HashMap<Integer, ItemStack>();
+
+        ItemStack[] inventory = getContents();
+        for (int i = 0; i < inventory.length; i++) {
+            if (item.equals(inventory[i])) {
+                slots.put( i, item );
+            }
+        }
+        return slots;
+    }
+
+    public int first(int materialId) {
+        ItemStack[] inventory = getContents();
+        for (int i = 0; i < inventory.length; i++) {
+            if (inventory[i].getTypeID() == materialId) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public int first(Material material) {
+        return first(material.getID());
+    }
+
+    public int first(ItemStack item) {
+        ItemStack[] inventory = getContents();
+        for (int i = 0; i < inventory.length; i++) {
+            if (item.equals(inventory[i])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public int firstEmpty() {
+        return first(Material.Air);
+    }
+
+    public int firstPartial(int materialId) {
+        ItemStack[] inventory = getContents();
+        for (int i = 0; i < inventory.length; i++) {
+            if (inventory[i].getAmount() <= inventory[i].getMaxStackSize()) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public int firstPartial(Material material) {
+        return firstPartial(material.getID());
+    }
+
+    public int firstPartial(ItemStack item) {
+        return firstPartial(item.getTypeID());
+    }
+
+    public HashMap<Integer,ItemStack> addItem(ItemStack... items) {
+        HashMap<Integer,ItemStack> leftover = new HashMap<Integer,ItemStack>();
+
+        /* TODO: some optimization
+         *  - Create a 'firstPartial' with a 'fromIndex'
+         *  - Record the lastPartial per Material
+         *  - Cache firstEmpty result
+         */
+
+        for (int i = 0; i < items.length; i++) {
+            ItemStack item = items[i];
+            while (true) {
+                // Do we already have a stack of it?
+                int firstPartial = firstPartial( item.getTypeID() );
+
+                // Drat! no partial stack
+                if (firstPartial == -1) {
+                    // Find a free spot!
+                    int firstFree = firstEmpty();
+
+                    if (firstFree == -1) {
+                        // No space at all!
+                        leftover.put(i, item);
+                    } else {
+                        // Just store it
+                        setItem( firstFree, item );
+                    }
+                    break;
+                }
+
+                // So, apparently it might only partially fit, well lets do just that
+                ItemStack partialItem = getItem(firstPartial);
+
+                int amount = item.getAmount();
+                int partialAmount = partialItem.getAmount();
+                int maxAmount = partialItem.getMaxStackSize();
+
+                // Check if it fully fits
+                if (amount + partialAmount <= maxAmount) {
+                    partialItem.setAmount( amount + partialAmount );
+                    break;
+                }
+
+                // It fits partially
+                partialItem.setAmount( maxAmount );
+                item.setAmount( amount + partialAmount - maxAmount );
+            }
+        }
+        return leftover;
+    }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventoryPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventoryPlayer.java
new file mode 100644
index 0000000000..3ee882fc60
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftInventoryPlayer.java
@@ -0,0 +1,67 @@
+package org.bukkit.craftbukkit;
+
+import java.util.ArrayList;
+
+import net.minecraft.server.InventoryPlayer;
+
+import org.bukkit.ItemStack;
+import org.bukkit.PlayerInventory;
+
+public class CraftInventoryPlayer extends CraftInventory implements PlayerInventory {
+    public CraftInventoryPlayer(net.minecraft.server.InventoryPlayer inventory) {
+        super(inventory);
+    }
+    
+    public InventoryPlayer getInventory() {
+        return (InventoryPlayer) inventory;
+    }
+
+    public ArrayList<ItemStack> getArmorContents() {
+        ArrayList<ItemStack> items = new ArrayList<ItemStack>();
+        for (net.minecraft.server.ItemStack item : getInventory().getArmorContents()) {
+            ItemStack i = null;
+            if (item != null) {
+                i = new CraftItemStack(item);
+            }
+            items.add(i);
+        }
+
+        return items;
+    }
+
+    public ItemStack getItemInHand() {
+        return new CraftItemStack( getInventory().e() );
+    }
+
+    public ItemStack getHelmet() {
+        return getItem( getSize() - 4 );
+    }
+
+    public ItemStack getChestplate() {
+        return getItem( getSize() - 3 );
+    }
+
+    public ItemStack getLeggings() {
+        return getItem( getSize() - 2 );
+    }
+
+    public ItemStack getBoots() {
+        return getItem( getSize() - 1 );
+    }
+
+    public void setHelmet(ItemStack helmet) {
+        setItem( getSize() - 4, helmet );
+    }
+
+    public void setChestplate(ItemStack chestplate) {
+        setItem( getSize() - 3, chestplate );
+    }
+
+    public void setLeggings(ItemStack leggings) {
+        setItem( getSize() - 2, leggings );
+    }
+
+    public void setBoots(ItemStack boots) {
+        setItem( getSize() - 1, boots );
+    }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java
index 3527721b05..d1571ac46f 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftItemStack.java
@@ -12,7 +12,7 @@ public class CraftItemStack extends ItemStack {
     }
 
     /*
-     * Unsure if we have to syn before each of these calls the values in 'item'
+     * Unsure if we have to sync before each of these calls the values in 'item'
      * are all public.
      */
 
@@ -82,4 +82,8 @@ public class CraftItemStack extends ItemStack {
         }
     }
 
+    @Override
+    public int getMaxStackSize() {
+        return item.a().b();
+    }
 }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSlot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSlot.java
new file mode 100644
index 0000000000..32b12b7a0f
--- /dev/null
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSlot.java
@@ -0,0 +1,25 @@
+package org.bukkit.craftbukkit;
+
+import org.bukkit.Inventory;
+import org.bukkit.ItemStack;
+import net.minecraft.server.Slot;
+
+public class CraftSlot implements org.bukkit.Slot {
+    private final Slot slot;
+
+    public CraftSlot(Slot slot) {
+        this.slot = slot;
+    }
+
+    public Inventory getInventory() {
+        return new CraftInventory( slot.b );
+    }
+
+    public int getIndex() {
+        return slot.a;
+    }
+
+    public ItemStack getItem() {
+        return new CraftItemStack( slot.c() );
+    }
+}
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStorageMinecart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStorageMinecart.java
index 7567529e31..3063482daa 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStorageMinecart.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStorageMinecart.java
@@ -1,11 +1,8 @@
 package org.bukkit.craftbukkit;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import net.minecraft.server.EntityMinecart;
 
-import org.bukkit.ItemStack;
+import org.bukkit.Inventory;
 import org.bukkit.StorageMinecart;
 
 /**
@@ -14,32 +11,14 @@ import org.bukkit.StorageMinecart;
  * @author sk89q
  */
 public class CraftStorageMinecart extends CraftMinecart implements StorageMinecart {
+    private CraftInventory inventory;
+    
     public CraftStorageMinecart(CraftServer server, EntityMinecart entity) {
         super(server, entity);
+        inventory = new CraftInventory( entity );
     }
 
-    public int getSize() {
-        return minecart.c();
-    }
-
-    public String getName() {
-        return minecart.b();
-    }
-
-    public ItemStack getItem(int index) {
-        return new CraftItemStack(minecart.a(index));
-    }
-
-    public List<ItemStack> getContents() {
-        ArrayList<ItemStack> items = new ArrayList<ItemStack>();
-        for (net.minecraft.server.ItemStack item: minecart.getContents()) {
-            ItemStack i = null;
-            if (item != null) {
-                i = new CraftItemStack( item );
-            }
-            items.add(i);
-        }
-
-        return items;
+    public Inventory getInventory() {
+        return inventory;
     }
 }