diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3fb1215c5a..9b00bb7f15 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -834,6 +834,8 @@ public abstract class MinecraftServer implements Runnable, IMojangStatistics, IC
     }
 
     public List a(ICommandListener icommandlistener, String s) {
+        // CraftBukkit start - Allow tab-completion of Bukkit commands
+        /*
         ArrayList arraylist = new ArrayList();
 
         if (s.startsWith("/")) {
@@ -872,6 +874,9 @@ public abstract class MinecraftServer implements Runnable, IMojangStatistics, IC
 
             return arraylist;
         }
+        */
+        return this.server.tabComplete(icommandlistener, s);
+        // CraftBukkit end
     }
 
     public static MinecraftServer getServer() {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0c55945b20..56ae1420cc 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -58,6 +58,7 @@ import org.bukkit.World;
 import org.bukkit.World.Environment;
 import org.bukkit.WorldCreator;
 import org.bukkit.command.Command;
+import org.bukkit.command.CommandException;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.ConsoleCommandSender;
 import org.bukkit.command.PluginCommand;
@@ -1234,4 +1235,41 @@ public final class CraftServer implements Server {
     public WarningState getWarningState() {
         return warningState;
     }
+
+    public List<String> tabComplete(net.minecraft.server.ICommandListener sender, String message) {
+        if (!(sender instanceof EntityPlayer)) {
+            return ImmutableList.of();
+        }
+
+        Player player = ((EntityPlayer) sender).getBukkitEntity();
+        if (message.startsWith("/")) {
+            return tabCompleteCommand(player, message);
+        } else {
+            return tabCompleteChat(player, message);
+        }
+    }
+
+    public List<String> tabCompleteCommand(Player player, String message) {
+        List<String> completions = null;
+        try {
+            completions = getCommandMap().tabComplete(player, message.substring(1));
+        } catch (CommandException ex) {
+            player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to tab-complete this command");
+            getLogger().log(Level.SEVERE, "Exception when " + player.getName() + " attempted to tab complete " + message, ex);
+        }
+        
+        return completions == null ? ImmutableList.<String>of() : completions;
+    }
+
+    public List<String> tabCompleteChat(Player player, String message) {
+        Player[] players = getOnlinePlayers();
+        List<String> completions = new ArrayList<String>(players.length);
+        for (Player p : players) {
+            if (player.canSee(p)) {
+                completions.add(p.getName());
+            }
+        }
+
+        return completions;
+    }
 }