* @param direction The <code>Direction</code> to move in.
     * @param interactive Interactive mode: play sounds and emit errors.
     * @return True if the unit can possibly move further.
     */
    private boolean moveDirection(Unit unit, Direction direction,
                                  boolean interactive) {
        Location destination = unit.getDestination();

        // Consider all the move types
        switch (unit.getMoveType(direction)) {
        case MOVE_HIGH_SEAS:
            if (destination == null) {
                return moveHighSeas(unit, direction);
            } else if (destination instanceof Europe) {
                moveTo(unit, destination);
                return false;
            }
            // Fall through
        case MOVE:
            moveMove(unit, direction);
            return unit.getMovesLeft() > 0;
        case EXPLORE_LOST_CITY_RUMOUR:
            moveExplore(unit, direction);
            return false;
        case ATTACK_UNIT: case ATTACK_SETTLEMENT:
            moveAttack(unit, direction);
            return false;
        case EMBARK:
            moveEmbark(unit, direction);
            return false;
        case ENTER_INDIAN_SETTLEMENT_WITH_FREE_COLONIST:
            moveLearnSkill(unit, direction);
            return false;
        case ENTER_INDIAN_SETTLEMENT_WITH_SCOUT:
            moveScoutIndianSettlement(unit, direction);
            return false;
        case ENTER_INDIAN_SETTLEMENT_WITH_MISSIONARY:
            moveUseMissionary(unit, direction);
            return false;
        case ENTER_FOREIGN_COLONY_WITH_SCOUT:
            moveScoutColony(unit, direction);
            return false;
        case ENTER_SETTLEMENT_WITH_CARRIER_AND_GOODS:
            moveTrade(unit, direction);
            return false;

        case MOVE_NO_ACCESS_BEACHED:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                StringTemplate nation = getNationAt(unit.getTile(), direction);
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessBeached")
                    .addStringTemplate("%nation%", nation));
            }
            return false;
        case MOVE_NO_ACCESS_CONTACT:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                StringTemplate nation = getNationAt(unit.getTile(), direction);
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessContact")
                    .addStringTemplate("%nation%", nation));
            }
            return false;
        case MOVE_NO_ACCESS_GOODS:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                StringTemplate nation = getNationAt(unit.getTile(), direction);
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessGoods")
                    .addStringTemplate("%nation%", nation)
                    .addStringTemplate("%unit%", Messages.getLabel(unit)));
            }
            return false;
        case MOVE_NO_ACCESS_LAND:
            if (!moveDisembark(unit, direction)) {
                if (interactive) {
                    gui.playSound("sound.event.illegalMove");
                }
            }
            return false;
        case MOVE_NO_ACCESS_SETTLEMENT:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                StringTemplate nation = getNationAt(unit.getTile(), direction);
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessSettlement")
                    .addStringTemplate("%unit%", Messages.getLabel(unit))
                    .addStringTemplate("%nation%", nation));
            }
            return false;
        case MOVE_NO_ACCESS_SKILL:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessSkill")
                    .addStringTemplate("%unit%", Messages.getLabel(unit)));
            }
            return false;
        case MOVE_NO_ACCESS_TRADE:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                StringTemplate nation = getNationAt(unit.getTile(), direction);
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessTrade")
                    .addStringTemplate("%nation%", nation));
            }
            return false;
        case MOVE_NO_ACCESS_WAR:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                StringTemplate nation = getNationAt(unit.getTile(), direction);
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessWar")
                    .addStringTemplate("%nation%", nation));
            }
            return false;
        case MOVE_NO_ACCESS_WATER:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAccessWater")
                    .addStringTemplate("%unit%", Messages.getLabel(unit)));
            }
            return false;
        case MOVE_NO_ATTACK_MARINE:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
                gui.showInformationMessage(unit,
                    StringTemplate.template("move.noAttackWater")
                    .addStringTemplate("%unit%", Messages.getLabel(unit)));
            }
            return false;
        case MOVE_NO_MOVES:
            // The unit may have some moves left, but not enough
            // to move to the next node.
            unit.setState(UnitState.SKIPPED);
            return false;
        default:
            if (interactive) {
                gui.playSound("sound.event.illegalMove");
            }
            return false;
        }
    }