diff --git a/src/main/java/com/comandante/creeper/Main.java b/src/main/java/com/comandante/creeper/Main.java
index 13a9692c2fd9b5586352473d5762ad688d5898de..6a54a5b10daecac68a32404d6a9e9a29b50da526 100644
--- a/src/main/java/com/comandante/creeper/Main.java
+++ b/src/main/java/com/comandante/creeper/Main.java
@@ -1,5 +1,7 @@
 package com.comandante.creeper;
 
+import com.comandante.creeper.command.DefaultCommandHandler;
+import com.comandante.creeper.command.commands.CommandService;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.managers.PlayerManager;
 import com.comandante.creeper.managers.PlayerManagerMapDB;
@@ -64,8 +66,11 @@ public class Main {
         gameManager.getNpcManager().saveNpc(derper3);
         roomManager.getRoom(janitorialCloset.getRoomId()).addPresentNpc(derper3.getNpcId());
 
+        CommandService commandService = new CommandService();
+        DefaultCommandHandler defaultCommandHandler = new DefaultCommandHandler(gameManager, commandService);
+
         CreeperServer creeperServer = new CreeperServer(8080, db);
-        creeperServer.run(gameManager);
+        creeperServer.run(gameManager, defaultCommandHandler);
 
         System.out.println("Creeper started.");
     }
diff --git a/src/main/java/com/comandante/creeper/command/CommandType.java b/src/main/java/com/comandante/creeper/command/CommandType.java
deleted file mode 100644
index 9330bfc9b440624e8e2753c4e6bf6b6c0c20ebd3..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/command/CommandType.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.comandante.creeper.command;
-
-import java.util.Set;
-
-public interface CommandType {
-    String getDescription();
-
-    Set<String> getValidCommandTriggers();
-
-    boolean isCaseSensitive();
-
-}
diff --git a/src/main/java/com/comandante/creeper/command/CommandTypeHelper.java b/src/main/java/com/comandante/creeper/command/CommandTypeHelper.java
deleted file mode 100644
index 3ee868cc13d980cf4d0c30b933bab9b81751c4ab..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/command/CommandTypeHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.comandante.creeper.command;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterators;
-
-import java.util.Iterator;
-
-public class CommandTypeHelper {
-    public static CommandType getCommandType(CommandType[] commandTypes, String message) {
-        final String rootCommand = message.split(" ")[0];
-        for (CommandType commandType : commandTypes) {
-            Iterator<String> iterator = commandType.getValidCommandTriggers().iterator();
-            String searchString = null;
-            if (!commandType.isCaseSensitive()) {
-                iterator = Iterators.transform(iterator, new UpperCaseFunction<String, String>());
-                searchString = rootCommand.toUpperCase();
-            } else {
-                searchString = rootCommand;
-            }
-            while (iterator.hasNext()) {
-                String next = iterator.next();
-                if (next.equals(searchString)) {
-                    return commandType;
-                }
-            }
-        }
-        return DefaultCommandType.UNKNOWN;
-    }
-
-    static class UpperCaseFunction<F, T> implements Function<F, T> {
-        @Override
-        public Object apply(Object f) {
-            return f.toString().toUpperCase();
-        }
-    }
-
-}
diff --git a/src/main/java/com/comandante/creeper/command/DefaultCommandHandler.java b/src/main/java/com/comandante/creeper/command/DefaultCommandHandler.java
index 8ccce30c38f4ac7cbaf6af40352fc9e01f7db0f3..9569ca1827911dbb1cd46675689c7f92a8231034 100644
--- a/src/main/java/com/comandante/creeper/command/DefaultCommandHandler.java
+++ b/src/main/java/com/comandante/creeper/command/DefaultCommandHandler.java
@@ -1,80 +1,60 @@
 package com.comandante.creeper.command;
 
 
-import com.comandante.creeper.managers.MovementManager;
-import com.comandante.creeper.model.Movement;
+import com.comandante.creeper.command.commands.CommandService;
+import com.comandante.creeper.command.commands.GossipCommand;
+import com.comandante.creeper.command.commands.MovementCommand;
+import com.comandante.creeper.command.commands.SayCommand;
+import com.comandante.creeper.command.commands.TellCommand;
+import com.comandante.creeper.command.commands.UnknownCommand;
+import com.comandante.creeper.command.commands.WhoCommand;
+import com.comandante.creeper.command.commands.WhoamiCommand;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.model.Player;
-import com.comandante.creeper.model.Room;
 import com.comandante.creeper.server.CreeperSession;
-import com.google.common.base.Optional;
 import org.jboss.netty.channel.MessageEvent;
 
 public class DefaultCommandHandler {
 
     private final GameManager gameManager;
-    private final CreeperSession creeperSession;
-    private final MessageEvent event;
+    private final CommandService commandService;
 
-    public DefaultCommandHandler(GameManager gameManager, CreeperSession creeperSession, MessageEvent event) {
+    public DefaultCommandHandler(GameManager gameManager, CommandService commandService) {
         this.gameManager = gameManager;
-        this.creeperSession = creeperSession;
-        this.event = event;
+        this.commandService = commandService;
     }
 
-    public void handle(DefaultCommandType cmdType) {
-        final String originalMessage = cmdType.getOriginalMessage();
-        final Player player = _player();
-        Optional<Movement> movement = Optional.absent();
-
-        switch(cmdType) {
-            case MOVE_NORTH:
-                movement = MovementManager.moveNorth(cmdType, player, _currentRoom(), event);
-                break;
-            case MOVE_SOUTH:
-                movement = MovementManager.moveSouth(cmdType, player, _currentRoom(), event);
-                break;
-            case MOVE_EAST:
-                movement = MovementManager.moveEast(cmdType, player, _currentRoom(), event);
-                break;
-            case MOVE_WEST:
-                movement = MovementManager.moveWest(cmdType, player, _currentRoom(), event);
-                break;
-            case SAY:
-                gameManager.say(player, originalMessage.replaceFirst("^say ", ""));
-                break;
-            case TELL:
-                gameManager.tell(player, originalMessage);
-                break;
-            case GOSSIP:
-                gameManager.gossip(player, originalMessage.replaceFirst("^gossip ", ""));
-                break;
-            case WHO:
-                gameManager.who(player);
-                break;
-            case WHOAMI:
-                player.getChannel().write(player.getPlayerName() + "\r\n");
-                break;
-            case HELP:
-                gameManager.getHelpManager().printHelp(player, originalMessage);
-                break;
-            case UNKNOWN:
-                gameManager.currentRoomLogic(creeperSession, event);
-                break;
+    public void handle(MessageEvent e, CreeperSession creeperSession) {
+        String originalMessage = (String) e.getMessage();
+        String rootCommand = originalMessage.split(" ")[0].toLowerCase();
+        String playerId = new Player(creeperSession.getUsername().get()).getPlayerId();
+        if (GossipCommand.validTriggers.contains(rootCommand)){
+            GossipCommand gossipCommand = new GossipCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(gossipCommand);
         }
-
-        if (movement.isPresent()) {
-            gameManager.movePlayer(movement.get());
-            gameManager.currentRoomLogic(creeperSession, event);
+        else if (MovementCommand.validTriggers.contains(rootCommand)){
+            MovementCommand movementCommand = new MovementCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(movementCommand);
+        }
+        else if (SayCommand.validTriggers.contains(rootCommand)){
+            SayCommand sayCommand = new SayCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(sayCommand);
+        }
+        else if (TellCommand.validTriggers.contains(rootCommand)){
+            TellCommand tellCommand = new TellCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(tellCommand);
+        }
+        else if (WhoamiCommand.validTriggers.contains(rootCommand)){
+            WhoamiCommand whoamiCommand = new WhoamiCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(whoamiCommand);
+        }
+        else if (WhoCommand.validTriggers.contains(rootCommand)){
+            WhoCommand whoCommand = new WhoCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(whoCommand);
+        } else {
+            UnknownCommand unknownCommand = new UnknownCommand(playerId, gameManager, originalMessage);
+            commandService.processCommand(unknownCommand);
         }
     }
-
-    private Player _player() {
-        return gameManager.getPlayerManager().getPlayerByUsername(creeperSession.getUsername().get());
-    }
-
-    private Room _currentRoom() {
-        return gameManager.getPlayerCurrentRoom(_player()).get();
-    }
-
 }
+
diff --git a/src/main/java/com/comandante/creeper/command/DefaultCommandType.java b/src/main/java/com/comandante/creeper/command/DefaultCommandType.java
deleted file mode 100644
index cbca6622e228005f4d92f9f0e605083dde3201b4..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/command/DefaultCommandType.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package com.comandante.creeper.command;
-
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-public enum DefaultCommandType implements CommandType {
-    MOVE_NORTH(new HashSet<String>(Arrays.asList("n", "north")), false, "Move north."),
-    MOVE_SOUTH(new HashSet<String>(Arrays.asList("s", "south")), false, "Move south."),
-    MOVE_EAST(new HashSet<String>(Arrays.asList("e", "east")), false, "Move east."),
-    MOVE_WEST(new HashSet<String>(Arrays.asList("w", "west")), false, "Move west."),
-    SAY(new HashSet<String>(Arrays.asList("say")), false, "Say something to the current room."),
-    TELL(new HashSet<String>(Arrays.asList("tell", "t")), false, "Tell something to a player in private."),
-    GOSSIP(new HashSet<String>(Arrays.asList("gossip")), false, "Gossip to the entire server."),
-    WHO(new HashSet<String>(Arrays.asList("who")), false, "List who is logged into the server."),
-    WHOAMI(new HashSet<String>(Arrays.asList("whoami")), false, "Who am I?"),
-    HELP(new HashSet<String>(Arrays.asList("help")), false, "This is the help."),
-    UNKNOWN(new HashSet<String>(Arrays.asList("")), true, "");
-
-    private Set<String> validCommandTriggers;
-    private boolean caseSensitive;
-    private String description;
-    private String originalMessage;
-
-    DefaultCommandType(Set<String> triggers, boolean caseSensitive, String description) {
-        this.validCommandTriggers = triggers;
-        this.caseSensitive = caseSensitive;
-        this.description = description;
-    }
-
-    @Override
-    public String getDescription() {
-        return description;
-    }
-
-    @Override
-    public Set<String> getValidCommandTriggers() {
-        return validCommandTriggers;
-    }
-
-    public String getOriginalMessage() {
-        return originalMessage;
-    }
-
-    @Override
-    public boolean isCaseSensitive() {
-        return caseSensitive;
-    }
-
-    public void setOriginalMessage(String originalMessage) {
-        this.originalMessage = originalMessage;
-    }
-
-    public static CommandType getCommandTypeFromMessage(String message) {
-        DefaultCommandType commandType = (DefaultCommandType) CommandTypeHelper.getCommandType(DefaultCommandType.values(), message);
-        commandType.setOriginalMessage(message);
-        return commandType;
-    }
-}
diff --git a/src/main/java/com/comandante/creeper/command/commands/Command.java b/src/main/java/com/comandante/creeper/command/commands/Command.java
new file mode 100644
index 0000000000000000000000000000000000000000..eab784e79c8f167eb36b5c52795e0bd1aff68fda
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/Command.java
@@ -0,0 +1,61 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public abstract class Command implements Runnable {
+
+    private final String playerId;
+    private final GameManager gameManager;
+    private final String helpDescription;
+    private final ImmutableList validTriggers;
+    private final boolean isCaseSensitiveTriggers;
+    private final ArrayList<String> originalMessageParts;
+    private final String originalMessage;
+
+    public Command(String playerId, GameManager gameManager, String helpDescription, ImmutableList validTriggers, boolean isCaseSensitiveTriggers, String originalMessage) {
+        this.playerId = playerId;
+        this.gameManager = gameManager;
+        this.helpDescription = helpDescription;
+        this.validTriggers = validTriggers;
+        this.isCaseSensitiveTriggers = isCaseSensitiveTriggers;
+        this.originalMessageParts = getMessageParts(originalMessage);
+        this.originalMessage = originalMessage;
+    }
+
+    public ArrayList<String> getOriginalMessageParts() {
+        return originalMessageParts;
+    }
+
+    public String getPlayerId() {
+        return playerId;
+    }
+
+    public GameManager getGameManager() {
+        return gameManager;
+    }
+
+    public String getHelpDescription() {
+        return helpDescription;
+    }
+
+    public ImmutableList getValidTriggers() {
+        return validTriggers;
+    }
+
+    public boolean isCaseSensitiveTriggers() {
+        return isCaseSensitiveTriggers;
+    }
+
+    public String getOriginalMessage() {
+        return originalMessage;
+    }
+
+    private ArrayList<String> getMessageParts(String s) {
+        String[] split = s.split(" ");
+        return new ArrayList<String>(Arrays.asList(split));
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/CommandService.java b/src/main/java/com/comandante/creeper/command/commands/CommandService.java
new file mode 100644
index 0000000000000000000000000000000000000000..8709e6fb80af2640038c8ad376307cdfd4912dfb
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/CommandService.java
@@ -0,0 +1,20 @@
+package com.comandante.creeper.command.commands;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class CommandService {
+
+    private final ExecutorService executorService;
+
+    public CommandService() {
+        this.executorService = Executors.newFixedThreadPool(1);
+    }
+
+    public void processCommand(Command command) {
+        executorService.submit(command);
+    }
+
+
+
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/GossipCommand.java b/src/main/java/com/comandante/creeper/command/commands/GossipCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c24d17f1423db04d445ab4a46f4e9a722d0a778
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/GossipCommand.java
@@ -0,0 +1,25 @@
+package com.comandante.creeper.command.commands;
+
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.model.Player;
+import com.google.common.collect.ImmutableList;
+
+public class GossipCommand extends Command {
+
+    private final static String helpDescription = "Speak to the entire server.";
+    public final static ImmutableList validTriggers = new ImmutableList.Builder<String>().add(
+            "gossip".toLowerCase()
+    ).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public GossipCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+        Player player = getGameManager().getPlayerManager().getPlayer(getPlayerId());
+        getGameManager().gossip(player, getOriginalMessage().replaceFirst("^gossip ", ""));
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/MovementCommand.java b/src/main/java/com/comandante/creeper/command/commands/MovementCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..10179d22e203fd57219e483788f3ac6aa95143ee
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/MovementCommand.java
@@ -0,0 +1,77 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.model.Movement;
+import com.comandante.creeper.model.Player;
+import com.comandante.creeper.model.Room;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class MovementCommand extends Command {
+
+    private final static String helpDescription = "Movement command.";
+    public final static List<String> northTriggers = Arrays.asList("n", "north".toLowerCase());
+    public final static List<String> southTriggers = Arrays.asList("s", "south".toLowerCase());
+    public final static List<String> eastTriggers = Arrays.asList("e", "east".toLowerCase());
+    public final static List<String> westTriggers = Arrays.asList("w", "west".toLowerCase());
+    public final static ImmutableList validTriggers =
+            new ImmutableList.Builder<String>().addAll(northTriggers).addAll(southTriggers).addAll(eastTriggers).addAll(westTriggers).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public MovementCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+        final GameManager gameManager = getGameManager();
+        Player player = gameManager.getPlayerManager().getPlayer(getPlayerId());
+        Optional<Room> roomOptional = gameManager.getPlayerCurrentRoom(player);
+        if (!roomOptional.isPresent()) {
+            throw new RuntimeException("Player is not in a room, movement failed!");
+        }
+        Room currentRoom = roomOptional.get();
+        final String command = getOriginalMessageParts().get(0);
+        Movement movement = null;
+        if (!validTriggers.contains(command.toLowerCase())) {
+            throw new RuntimeException("Malformed movement command.");
+        }
+        if (northTriggers.contains(command.toLowerCase())) {
+            if (!currentRoom.getNorthId().isPresent()) {
+                player.getChannel().write("There's no northern exit.\r\n");
+                return;
+            }
+            Room destinationRoom = gameManager.getRoomManager().getRoom(currentRoom.getNorthId().get());
+            movement = new Movement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the north.");
+        }
+        if (southTriggers.contains(command.toLowerCase())) {
+            if (!currentRoom.getSouthId().isPresent()) {
+                player.getChannel().write("There's no southern exit.\r\n");
+                return;
+            }
+            Room destinationRoom = gameManager.getRoomManager().getRoom(currentRoom.getSouthId().get());
+            movement = new Movement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the south.");
+        }
+        if (eastTriggers.contains(command.toLowerCase())) {
+            if (!currentRoom.getEastId().isPresent()) {
+                player.getChannel().write("There's no eastern exit.\r\n");
+                return;
+            }
+            Room destinationRoom = gameManager.getRoomManager().getRoom(currentRoom.getEastId().get());
+            movement = new Movement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the east.");
+        }
+        if (westTriggers.contains(command.toLowerCase())) {
+            if (!currentRoom.getWestId().isPresent()) {
+                player.getChannel().write("There's no eastern exit.\r\n");
+                return;
+            }
+            Room destinationRoom = gameManager.getRoomManager().getRoom(currentRoom.getWestId().get());
+            movement = new Movement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the west.");
+        }
+        gameManager.movePlayer(movement);
+        gameManager.currentRoomLogic(movement.getPlayer().getPlayerId());
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/SayCommand.java b/src/main/java/com/comandante/creeper/command/commands/SayCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..c02ffe932e29e3c508585a0a91ad221d29f9209f
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/SayCommand.java
@@ -0,0 +1,25 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.model.Player;
+import com.google.common.collect.ImmutableList;
+
+public class SayCommand extends Command {
+
+    private final static String helpDescription = "Speak to members of your current room";
+    public final static ImmutableList validTriggers = new ImmutableList.Builder<String>().add(
+            "say".toLowerCase()
+    ).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public SayCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+        GameManager gameManager = getGameManager();
+        Player player = gameManager.getPlayerManager().getPlayer(getPlayerId());
+        getGameManager().say(player, getOriginalMessage().replaceFirst("^say ", ""));
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/TellCommand.java b/src/main/java/com/comandante/creeper/command/commands/TellCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..b40f04d2dc54fd45a8a7783ed0a3064ab2c8bb1e
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/TellCommand.java
@@ -0,0 +1,22 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.google.common.collect.ImmutableList;
+
+public class TellCommand extends Command {
+
+    private final static String helpDescription = "Speak to another player in private.";
+    public final static ImmutableList validTriggers = new ImmutableList.Builder<String>().add(
+            "tell".toLowerCase()
+    ).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public TellCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+        getGameManager().tell(getGameManager().getPlayerManager().getPlayer(getPlayerId()), getOriginalMessage());
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/UnknownCommand.java b/src/main/java/com/comandante/creeper/command/commands/UnknownCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..b92ad687b86777f705850491f1538e73e078c5de
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/UnknownCommand.java
@@ -0,0 +1,21 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.google.common.collect.ImmutableList;
+
+public class UnknownCommand extends Command {
+    private final static String helpDescription = "Unknown.";
+    public final static ImmutableList validTriggers = new ImmutableList.Builder<String>().add(
+            "".toLowerCase()
+    ).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public UnknownCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+        getGameManager().currentRoomLogic(getPlayerId());
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/WhoCommand.java b/src/main/java/com/comandante/creeper/command/commands/WhoCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8222cafcf0a98512c0d7a803c1c2211e26ec84d
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/WhoCommand.java
@@ -0,0 +1,24 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.model.Player;
+import com.google.common.collect.ImmutableList;
+
+public class WhoCommand extends Command {
+
+    private final static String helpDescription = "List players currently logged in to server.";
+    public final static ImmutableList validTriggers = new ImmutableList.Builder<String>().add(
+            "whoami".toLowerCase()
+    ).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public WhoCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+        Player player = getGameManager().getPlayerManager().getPlayer(getPlayerId());
+        player.getChannel().write(player.getPlayerName() + "\r\n");
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/commands/WhoamiCommand.java b/src/main/java/com/comandante/creeper/command/commands/WhoamiCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..063c062a90259214b775f8fbe5e0f14420c514ad
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/commands/WhoamiCommand.java
@@ -0,0 +1,22 @@
+package com.comandante.creeper.command.commands;
+
+import com.comandante.creeper.managers.GameManager;
+import com.google.common.collect.ImmutableList;
+
+public class WhoamiCommand extends Command {
+
+    private final static String helpDescription = "List who you are.";
+    public final static ImmutableList validTriggers = new ImmutableList.Builder<String>().add(
+            "who".toLowerCase()
+    ).build();
+    private final static boolean isCaseSensitiveTriggers = false;
+
+    public WhoamiCommand(String playerId, GameManager gameManager, String originalMessage) {
+        super(playerId, gameManager, helpDescription, validTriggers, isCaseSensitiveTriggers, originalMessage);
+    }
+
+    @Override
+    public void run() {
+
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/managers/GameManager.java b/src/main/java/com/comandante/creeper/managers/GameManager.java
index 2aafed3fd2fa00f6a3341290227c4f229322da40..2d902873109bc51ae37dab3970cb50efd464e238 100644
--- a/src/main/java/com/comandante/creeper/managers/GameManager.java
+++ b/src/main/java/com/comandante/creeper/managers/GameManager.java
@@ -1,12 +1,11 @@
 package com.comandante.creeper.managers;
 
 
-import com.comandante.creeper.command.DefaultCommandType;
 import com.comandante.creeper.model.Movement;
-import com.comandante.creeper.model.npc.Npc;
-import com.comandante.creeper.model.npc.NpcType;
 import com.comandante.creeper.model.Player;
 import com.comandante.creeper.model.Room;
+import com.comandante.creeper.model.npc.Npc;
+import com.comandante.creeper.model.npc.NpcType;
 import com.comandante.creeper.server.CreeperSession;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
@@ -25,17 +24,16 @@ public class GameManager {
 
     public static String LOGO =
             " ██████╗██████╗ ███████╗███████╗██████╗ ███████╗██████╗ \r\n" +
-            "██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██╔══██╗\r\n" +
-            "██║     ██████╔╝█████╗  █████╗  ██████╔╝█████╗  ██████╔╝\r\n" +
-            "██║     ██╔══██╗██╔══╝  ██╔══╝  ██╔═══╝ ██╔══╝  ██╔══██╗\r\n" +
-            "╚██████╗██║  ██║███████╗███████╗██║     ███████╗██║  ██║\r\n" +
-            " ╚═════╝╚═╝  ╚═╝╚══════╝╚══════╝╚═╝     ╚══════╝╚═╝  ╚═╝";
+                    "██╔════╝██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██╔══██╗\r\n" +
+                    "██║     ██████╔╝█████╗  █████╗  ██████╔╝█████╗  ██████╔╝\r\n" +
+                    "██║     ██╔══██╗██╔══╝  ██╔══╝  ██╔═══╝ ██╔══╝  ██╔══██╗\r\n" +
+                    "╚██████╗██║  ██║███████╗███████╗██║     ███████╗██║  ██║\r\n" +
+                    " ╚═════╝╚═╝  ╚═╝╚══════╝╚══════╝╚═╝     ╚══════╝╚═╝  ╚═╝";
 
     public static String VERSION = "0.1-SNAPSHOT";
 
     private final RoomManager roomManager;
     private final PlayerManager playerManager;
-    private final HelpManager helpManager;
     private final NewUserRegistrationManager newUserRegistrationManager;
     private final NPCManager npcManager;
 
@@ -47,7 +45,6 @@ public class GameManager {
         this.roomManager = roomManager;
         this.playerManager = playerManager;
         this.newUserRegistrationManager = new NewUserRegistrationManager(playerManager);
-        this.helpManager = new HelpManager();
         this.npcManager = new NPCManager(roomManager, playerManager);
     }
 
@@ -55,10 +52,6 @@ public class GameManager {
         return npcManager;
     }
 
-    public HelpManager getHelpManager() {
-        return helpManager;
-    }
-
     public RoomManager getRoomManager() {
         return roomManager;
     }
@@ -90,7 +83,7 @@ public class GameManager {
         stringBuilder.append("----------------------\r\n");
         stringBuilder.append("|--active users------|\r\n");
         stringBuilder.append("----------------------\r\n");
-        for (Player allPlayer: allPlayers) {
+        for (Player allPlayer : allPlayers) {
             stringBuilder.append(allPlayer.getPlayerName()).append("\r\n");
         }
         stringBuilder.append(new Ansi().reset().toString());
@@ -162,19 +155,8 @@ public class GameManager {
             for (Player next : playerManager.getPresentPlayers(sourceRoom)) {
                 StringBuilder sb = new StringBuilder();
                 sb.append(movement.getPlayer().getPlayerName());
-                if (movement.getOriginalMovementCommand().equals(DefaultCommandType.MOVE_NORTH)) {
-                    sb.append(" exited to the north.");
-                } else if (movement.getOriginalMovementCommand().equals(DefaultCommandType.MOVE_EAST)) {
-                    sb.append(" exited to the east.");
-                } else if (movement.getOriginalMovementCommand().equals(DefaultCommandType.MOVE_SOUTH)) {
-                    sb.append(" exited to the south.");
-                } else if (movement.getOriginalMovementCommand().equals(DefaultCommandType.MOVE_WEST)) {
-                    sb.append(" exited to the west.");
-                } else {
-                    sb.append(" exited.");
-                }
-                sb.append("\r\n");
-            next.getChannel().write(sb.toString());
+                sb.append(" ").append(movement.getRoomExitMessage()).append("\r\n");
+                next.getChannel().write(sb.toString());
             }
             for (Player next : playerManager.getPresentPlayers(destinationRoom)) {
                 next.getChannel().write(movement.getPlayer().getPlayerName() + " arrived.\r\n");
@@ -252,8 +234,8 @@ public class GameManager {
         return stringBuilder.toString();
     }
 
-    public void currentRoomLogic(CreeperSession creeperSession, MessageEvent e) {
-        final Player player = playerManager.getPlayerByUsername(creeperSession.getUsername().get());
+    public void currentRoomLogic(String playerId) {
+        Player player = playerManager.getPlayer(playerId);
         final Room playerCurrentRoom = getPlayerCurrentRoom(player).get();
         StringBuilder sb = new StringBuilder();
         sb.append(playerCurrentRoom.getRoomDescription()).append("\r\n");
@@ -273,4 +255,9 @@ public class GameManager {
         player.getChannel().write(sb.toString());
     }
 
+    public void currentRoomLogic(CreeperSession creeperSession, MessageEvent e) {
+        final String player = playerManager.getPlayerByUsername(creeperSession.getUsername().get()).getPlayerId();
+        currentRoomLogic(player);
+    }
+
 }
diff --git a/src/main/java/com/comandante/creeper/managers/HelpManager.java b/src/main/java/com/comandante/creeper/managers/HelpManager.java
deleted file mode 100644
index a513b6bb9083015ea0da5ab4837e1b8f71ae5bb7..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/managers/HelpManager.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.comandante.creeper.managers;
-
-
-import com.comandante.creeper.command.DefaultCommandType;
-import com.comandante.creeper.model.Player;
-import org.fusesource.jansi.Ansi;
-
-public class HelpManager {
-
-    public void printHelp(Player player, String originalMessage) {
-        StringBuilder sb = new StringBuilder();
-        DefaultCommandType[] values = DefaultCommandType.values();
-        sb.append(new Ansi().fg(Ansi.Color.RED).toString());
-        for (DefaultCommandType defaultCommandType : values) {
-            if (defaultCommandType.equals(DefaultCommandType.UNKNOWN)) {
-                continue;
-            }
-            sb.append(defaultCommandType.getValidCommandTriggers()).append(" ").append(defaultCommandType.getDescription()).append("\r\n");
-        }
-        sb.append(new Ansi().reset().toString()).append("\r\n");
-        player.getChannel().write(sb.toString());
-    }
-}
diff --git a/src/main/java/com/comandante/creeper/managers/MovementManager.java b/src/main/java/com/comandante/creeper/managers/MovementManager.java
deleted file mode 100644
index 00938df63a9341a4eeb22950d082b951da5f7d5d..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/managers/MovementManager.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.comandante.creeper.managers;
-
-import com.comandante.creeper.command.CommandType;
-import com.comandante.creeper.model.Movement;
-import com.comandante.creeper.model.Player;
-import com.comandante.creeper.model.Room;
-import com.google.common.base.Optional;
-import org.jboss.netty.channel.MessageEvent;
-
-public class MovementManager {
-
-    public static Optional<Movement> moveNorth(CommandType cmdType, Player player, Room currentRoom, MessageEvent event) {
-        if (!currentRoom.getNorthId().isPresent()) {
-            event.getChannel().write("There's no northern exit.\r\n");
-            return Optional.absent();
-        }
-        return Optional.of(
-                new Movement(player, currentRoom.getRoomId(), currentRoom.getNorthId().get(), cmdType));
-    }
-
-    public static Optional<Movement> moveSouth(CommandType cmdType, Player player, Room currentRoom, MessageEvent event) {
-        if (!currentRoom.getSouthId().isPresent()) {
-            event.getChannel().write("There's no southern exit.\r\n");
-            return Optional.absent();
-        }
-        return Optional.of(
-                new Movement(player, currentRoom.getRoomId(), currentRoom.getSouthId().get(), cmdType));
-    }
-
-    public static Optional<Movement> moveEast(CommandType cmdType, Player player, Room currentRoom, MessageEvent event) {
-        if (!currentRoom.getEastId().isPresent()) {
-            event.getChannel().write("There's no eastern exit.\r\n");
-            return Optional.absent();
-        }
-        return Optional.of(
-                new Movement(player, currentRoom.getRoomId(), currentRoom.getEastId().get(), cmdType));
-    }
-
-    public static Optional<Movement> moveWest(CommandType cmdType, Player player, Room currentRoom, MessageEvent event) {
-        if (!currentRoom.getWestId().isPresent()) {
-            event.getChannel().write("There's no western exit.\r\n");
-            return Optional.absent();
-        }
-        return Optional.of(
-                new Movement(player, currentRoom.getRoomId(), currentRoom.getWestId().get(), cmdType));
-    }
-}
diff --git a/src/main/java/com/comandante/creeper/model/Movement.java b/src/main/java/com/comandante/creeper/model/Movement.java
index 9b1dfe48a28b2262040eac3d9c24b8f7f050c2c6..b6106eb070aafb7d3b7ee22400fe6e8e22d282f7 100644
--- a/src/main/java/com/comandante/creeper/model/Movement.java
+++ b/src/main/java/com/comandante/creeper/model/Movement.java
@@ -1,19 +1,25 @@
 package com.comandante.creeper.model;
 
-import com.comandante.creeper.command.CommandType;
+import com.comandante.creeper.command.commands.MovementCommand;
 
 public class Movement {
 
     private final Player player;
     private final Integer sourceRoomId;
     private final Integer destinationRoomId;
-    private final CommandType originalMovementCommand;
-
-    public Movement(Player player, Integer sourceRoomId, Integer destinationRoomId, CommandType originalMovementCommand) {
+    private final MovementCommand command;
+    private final String roomExitMessage;
+
+    public Movement(Player player,
+                    Integer sourceRoomId,
+                    Integer destinationRoomId,
+                    MovementCommand command,
+                    String roomExitMessage) {
         this.player = player;
         this.sourceRoomId = sourceRoomId;
         this.destinationRoomId = destinationRoomId;
-        this.originalMovementCommand = originalMovementCommand;
+        this.command = command;
+        this.roomExitMessage = roomExitMessage;
     }
 
     public Integer getSourceRoomId() {
@@ -28,7 +34,11 @@ public class Movement {
         return player;
     }
 
-    public CommandType getOriginalMovementCommand() {
-        return originalMovementCommand;
+    public String getRoomExitMessage() {
+        return roomExitMessage;
+    }
+
+    public MovementCommand getCommand() {
+        return command;
     }
 }
diff --git a/src/main/java/com/comandante/creeper/server/CreeperServer.java b/src/main/java/com/comandante/creeper/server/CreeperServer.java
index a881d5f15feba2f33c7754cba37b58ca1ca69e63..a4c21e09e62abf0405c09614f3b79ef96424b3ee 100644
--- a/src/main/java/com/comandante/creeper/server/CreeperServer.java
+++ b/src/main/java/com/comandante/creeper/server/CreeperServer.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.server;
 
 
+import com.comandante.creeper.command.DefaultCommandHandler;
 import com.comandante.creeper.managers.GameManager;
 import org.jboss.netty.bootstrap.ServerBootstrap;
 import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
@@ -19,9 +20,9 @@ public class CreeperServer {
         this.db = db;
     }
 
-    public void run(GameManager gameManager) throws Exception {
+    public void run(GameManager gameManager, DefaultCommandHandler defaultCommandHandler) throws Exception {
         ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
-        CreeperServerHandler handler = new CreeperServerHandler(new CreeperMapDBAuthenticator(gameManager), gameManager);
+        CreeperServerHandler handler = new CreeperServerHandler(new CreeperMapDBAuthenticator(gameManager), gameManager, defaultCommandHandler);
         bootstrap.setPipelineFactory(new CreeperServerPipelineFactory(handler));
         bootstrap.bind(new InetSocketAddress(8080));
     }
diff --git a/src/main/java/com/comandante/creeper/server/CreeperServerHandler.java b/src/main/java/com/comandante/creeper/server/CreeperServerHandler.java
index f9c9d18ea5b12c952b552f0bf64d21d4dc3109cf..369b7ef0239fd89ea17623aac728d37d4c3a3bf0 100644
--- a/src/main/java/com/comandante/creeper/server/CreeperServerHandler.java
+++ b/src/main/java/com/comandante/creeper/server/CreeperServerHandler.java
@@ -1,7 +1,6 @@
 package com.comandante.creeper.server;
 
 import com.comandante.creeper.command.DefaultCommandHandler;
-import com.comandante.creeper.command.DefaultCommandType;
 import com.comandante.creeper.managers.GameManager;
 import com.google.common.base.Optional;
 import org.fusesource.jansi.Ansi;
@@ -14,12 +13,14 @@ import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 
 public class CreeperServerHandler extends SimpleChannelUpstreamHandler {
 
-    CreeperAuthenticator creeperAuthenticator;
-    GameManager gameManager;
+    private final CreeperAuthenticator creeperAuthenticator;
+    private final GameManager gameManager;
+    private final DefaultCommandHandler defaultCommandHandler;
 
-    public CreeperServerHandler(CreeperAuthenticator creeperAuthenticator, GameManager gameManager) {
+    public CreeperServerHandler(CreeperAuthenticator creeperAuthenticator, GameManager gameManager, DefaultCommandHandler defaultCommandHandler) {
         this.creeperAuthenticator = creeperAuthenticator;
         this.gameManager = gameManager;
+        this.defaultCommandHandler = defaultCommandHandler;
     }
 
     @Override
@@ -61,10 +62,8 @@ public class CreeperServerHandler extends SimpleChannelUpstreamHandler {
                 gameManager.currentRoomLogic(creeperSession, e);
             }
         } else {
-            DefaultCommandHandler cmdHandler = new DefaultCommandHandler(gameManager, creeperSession, e);
-            DefaultCommandType cmdType =
-                    (DefaultCommandType) DefaultCommandType.getCommandTypeFromMessage(((String) e.getMessage()));
-            cmdHandler.handle(cmdType);
+            defaultCommandHandler.handle(e, creeperSession);
+
         }
     }