diff --git a/pom.xml b/pom.xml
index 9628e8bc23..c067169138 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,11 @@
       <artifactId>jopt-simple</artifactId>
       <version>3.2</version>
     </dependency>
+    <dependency>
+      <groupId>jline</groupId>
+      <artifactId>jline</artifactId>
+      <version>0.9.94</version>
+    </dependency>
   </dependencies>
   <!-- This builds a completely 'ready to start' jar with all dependencies inside -->
   <build>
diff --git a/src/main/java/net/minecraft/server/ConsoleLogManager.java b/src/main/java/net/minecraft/server/ConsoleLogManager.java
index 6de400b418..641c8ca71a 100644
--- a/src/main/java/net/minecraft/server/ConsoleLogManager.java
+++ b/src/main/java/net/minecraft/server/ConsoleLogManager.java
@@ -6,6 +6,9 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import java.util.logging.Handler; // CraftBukkit
+import jline.ConsoleReader;
+import org.bukkit.craftbukkit.util.ShortConsoleLogFormatter;
+import org.bukkit.craftbukkit.util.TerminalConsoleHandler;
 
 public class ConsoleLogManager {
 
@@ -14,11 +17,12 @@ public class ConsoleLogManager {
 
     public ConsoleLogManager() {}
 
-    public static void a() {
+    // Craftbukkit - change of method signature!
+    public static void a(ConsoleReader reader) {
         ConsoleLogFormatter consolelogformatter = new ConsoleLogFormatter();
 
         a.setUseParentHandlers(false);
-        ConsoleHandler consolehandler = new ConsoleHandler();
+        ConsoleHandler consolehandler = new TerminalConsoleHandler(reader);
 
         // CraftBukkit start
         for (Handler handler: global.getHandlers()) {
@@ -26,7 +30,7 @@ public class ConsoleLogManager {
         }
         // CraftBukkit end
 
-        consolehandler.setFormatter(consolelogformatter);
+        consolehandler.setFormatter(new ShortConsoleLogFormatter()); // Craftbukkit
         a.addHandler(consolehandler);
         global.addHandler(consolehandler); // CraftBukkit
 
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 3daaa767dc..71e6a327fa 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -15,10 +15,12 @@ import java.util.logging.Logger;
 // CraftBukkit start
 import java.io.PrintStream;
 import java.net.UnknownHostException;
+import jline.ConsoleReader;
 import joptsimple.OptionSet;
 import org.bukkit.command.ConsoleCommandSender;
 import org.bukkit.craftbukkit.CraftServer;
 import org.bukkit.craftbukkit.LoggerOutputStream;
+import org.bukkit.craftbukkit.command.ColouredConsoleSender;
 import org.bukkit.craftbukkit.scheduler.CraftScheduler;
 import org.bukkit.event.Event;
 import org.bukkit.event.world.WorldEvent;
@@ -50,12 +52,21 @@ public class MinecraftServer implements Runnable, ICommandListener {
     public List<WorldServer> worlds = new ArrayList<WorldServer>();
     public CraftServer server;
     public OptionSet options;
-    public ConsoleCommandSender console;
+    public ColouredConsoleSender console;
+    public ConsoleReader reader;
     // Craftbukkit end
 
     public MinecraftServer(OptionSet options) { // CraftBukkit - adds argument OptionSet
         new ThreadSleepForever(this);
-        this.options = options; // CraftBukkit
+
+         // CraftBukkit start
+        this.options = options;
+        try {
+            this.reader = new ConsoleReader();
+        } catch (IOException ex) {
+            Logger.getLogger(MinecraftServer.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        // CraftBukkit end
     }
 
     private boolean d() throws UnknownHostException { // CraftBukkit - added throws UnknownHostException
@@ -64,7 +75,7 @@ public class MinecraftServer implements Runnable, ICommandListener {
 
         threadcommandreader.setDaemon(true);
         threadcommandreader.start();
-        ConsoleLogManager.a();
+        ConsoleLogManager.a(reader); // Craftbukkit
 
         // CraftBukkit start
         System.setOut(new PrintStream(new LoggerOutputStream(a, Level.INFO), true));
diff --git a/src/main/java/net/minecraft/server/ServerConfigurationManager.java b/src/main/java/net/minecraft/server/ServerConfigurationManager.java
index 7f26ef18ea..15a1e554ee 100644
--- a/src/main/java/net/minecraft/server/ServerConfigurationManager.java
+++ b/src/main/java/net/minecraft/server/ServerConfigurationManager.java
@@ -17,6 +17,7 @@ import org.bukkit.Location;
 import org.bukkit.command.ConsoleCommandSender;
 import org.bukkit.craftbukkit.CraftServer;
 import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.craftbukkit.command.ColouredConsoleSender;
 import org.bukkit.entity.Player;
 import org.bukkit.event.Event;
 import org.bukkit.event.Event.Type;
@@ -48,7 +49,7 @@ public class ServerConfigurationManager {
 
     public ServerConfigurationManager(MinecraftServer minecraftserver) {
         minecraftserver.server = new CraftServer(minecraftserver, this);
-        minecraftserver.console = new ConsoleCommandSender(minecraftserver.server);
+        minecraftserver.console = new ColouredConsoleSender(minecraftserver.server);
         server = minecraftserver.server;
         // CraftBukkit end
 
diff --git a/src/main/java/net/minecraft/server/ThreadCommandReader.java b/src/main/java/net/minecraft/server/ThreadCommandReader.java
new file mode 100644
index 0000000000..7277758e80
--- /dev/null
+++ b/src/main/java/net/minecraft/server/ThreadCommandReader.java
@@ -0,0 +1,34 @@
+package net.minecraft.server;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jline.ConsoleReader;
+
+public class ThreadCommandReader extends Thread {
+
+    final MinecraftServer a;
+
+    public ThreadCommandReader(MinecraftServer minecraftserver) {
+        this.a = minecraftserver;
+    }
+
+    public void run() {
+        // Craftbukkit start - whole method, nuked to oblivion! :o
+
+        try {
+            ConsoleReader reader = a.reader;
+            String line = null;
+
+            while ((!this.a.g) && (MinecraftServer.a(this.a)) && ((line = reader.readLine()) != null)) {
+                this.a.a(line, (ICommandListener) this.a);
+            }
+
+        } catch (IOException ex) {
+            Logger.getLogger(ThreadCommandReader.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        // Craftbukkit end
+    }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 282642578e..93b9a7d7ce 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -9,6 +9,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import jline.ConsoleReader;
 import net.minecraft.server.ChunkCoordinates;
 import net.minecraft.server.ConvertProgressUpdater;
 import net.minecraft.server.Convertable;
@@ -276,4 +277,8 @@ public final class CraftServer implements Server {
     public Logger getLogger() {
         return MinecraftServer.a;
     }
+
+    public ConsoleReader getReader() {
+        return console.reader;
+    }
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
new file mode 100644
index 0000000000..8bf86e0a11
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
@@ -0,0 +1,54 @@
+package org.bukkit.craftbukkit.command;
+
+import java.util.EnumMap;
+import java.util.Map;
+import jline.ANSIBuffer.ANSICodes;
+import jline.ConsoleReader;
+import jline.Terminal;
+import org.bukkit.ChatColor;
+import org.bukkit.command.ConsoleCommandSender;
+import org.bukkit.craftbukkit.CraftServer;
+
+public class ColouredConsoleSender extends ConsoleCommandSender {
+    private final ConsoleReader reader;
+    private final Terminal terminal;
+    private final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
+    private final ChatColor[] colors = ChatColor.values();
+
+    public ColouredConsoleSender(CraftServer server) {
+        super(server);
+        this.reader = server.getReader();
+        this.terminal = reader.getTerminal();
+
+        replacements.put(ChatColor.BLACK, ANSICodes.attrib(0));
+        replacements.put(ChatColor.RED, ANSICodes.attrib(31));
+        replacements.put(ChatColor.DARK_RED, ANSICodes.attrib(31));
+        replacements.put(ChatColor.GREEN, ANSICodes.attrib(32));
+        replacements.put(ChatColor.DARK_GREEN, ANSICodes.attrib(32));
+        replacements.put(ChatColor.YELLOW, ANSICodes.attrib(33));
+        replacements.put(ChatColor.BLUE, ANSICodes.attrib(34));
+        replacements.put(ChatColor.DARK_BLUE, ANSICodes.attrib(34));
+        replacements.put(ChatColor.LIGHT_PURPLE, ANSICodes.attrib(35));
+        replacements.put(ChatColor.DARK_PURPLE, ANSICodes.attrib(35));
+        replacements.put(ChatColor.AQUA, ANSICodes.attrib(36));
+        replacements.put(ChatColor.WHITE, ANSICodes.attrib(37));
+    }
+
+    @Override
+    public void sendMessage(String message) {
+        if (terminal.isANSISupported()) {
+            String result = message;
+
+            for (ChatColor color : colors) {
+                if (replacements.containsKey(color)) {
+                    result = result.replaceAll(color.toString(), replacements.get(color));
+                } else {
+                    result = result.replaceAll(color.toString(), "");
+                }
+            }
+            System.out.println(result + ANSICodes.attrib(0));
+        } else {
+            super.sendMessage(message);
+        }
+    }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java b/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java
new file mode 100644
index 0000000000..ad4419f9aa
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java
@@ -0,0 +1,33 @@
+package org.bukkit.craftbukkit.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+public class ShortConsoleLogFormatter extends Formatter {
+    private final SimpleDateFormat date = new SimpleDateFormat("HH:mm:ss");
+
+    @Override
+    public String format(LogRecord record) {
+        StringBuilder builder = new StringBuilder();
+        Throwable ex = record.getThrown();
+
+        builder.append(date.format(record.getMillis()));
+        builder.append(" [");
+        builder.append(record.getLevel().getLocalizedName().toUpperCase());
+        builder.append("] ");
+        builder.append(record.getMessage());
+        builder.append('\n');
+
+        if (ex != null) {
+            StringWriter writer = new StringWriter();
+            ex.printStackTrace(new PrintWriter(writer));
+            builder.append(writer);
+        }
+
+        return builder.toString();
+    }
+    
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleHandler.java b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleHandler.java
new file mode 100644
index 0000000000..a7beb5587d
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleHandler.java
@@ -0,0 +1,27 @@
+package org.bukkit.craftbukkit.util;
+
+import java.io.IOException;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import jline.ConsoleReader;
+
+public class TerminalConsoleHandler extends ConsoleHandler {
+    private final ConsoleReader reader;
+
+    public TerminalConsoleHandler(ConsoleReader reader) {
+        super();
+        this.reader = reader;
+    }
+
+    @Override
+    public synchronized void flush() {
+        super.flush();
+        try {
+            reader.redrawLine();
+        } catch (IOException ex) {
+            Logger.getLogger(TerminalConsoleHandler.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+}