Index: uspace/app/bdsh/input.c
===================================================================
--- uspace/app/bdsh/input.c	(revision 89660f22a2e2b7867763e40b0d9947f1df5622b3)
+++ uspace/app/bdsh/input.c	(revision 0662451c35f4872031fe346116ad27f80b39296d)
@@ -67,9 +67,10 @@
 {
 	char *cmd[WORD_MAX];
+	token_t tokens_space[WORD_MAX];
+	token_t *tokens = tokens_space;
 	int rc = 0;
 	tokenizer_t tok;
-	int i, pipe_count, processed_pipes;
-	int pipe_pos[2];
-	char **actual_cmd;
+	unsigned int i, pipe_count, processed_pipes;
+	unsigned int pipe_pos[2];
 	char *redir_from = NULL;
 	char *redir_to = NULL;
@@ -78,12 +79,22 @@
 		return CL_EFAIL;
 
-	rc = tok_init(&tok, usr->line, cmd, WORD_MAX);
+	rc = tok_init(&tok, usr->line, tokens, WORD_MAX);
 	if (rc != EOK) {
 		goto finit;
 	}
 	
-	rc = tok_tokenize(&tok);
+	size_t tokens_length;
+	rc = tok_tokenize(&tok, &tokens_length);
 	if (rc != EOK) {
 		goto finit;
+	}
+	
+	if (tokens_length > 0 && tokens[0].type == TOKTYPE_SPACE) {
+		tokens++;
+		tokens_length--;
+	}
+	
+	if (tokens_length > 0 && tokens[tokens_length-1].type == TOKTYPE_SPACE) {
+		tokens_length--;
 	}
 	
@@ -93,7 +104,6 @@
 	 * First find the pipes and check that there are no more
 	 */
-	int cmd_length = 0;
-	for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) {
-		if (cmd[i][0] == '|') {
+	for (i = 0, pipe_count = 0; i < tokens_length; i++) {
+		if (tokens[i].type == TOKTYPE_PIPE) {
 			if (pipe_count >= 2) {
 				print_pipe_usage();
@@ -106,12 +116,15 @@
 	}
 	
-	actual_cmd = cmd;
+	unsigned int cmd_token_start = 0;
+	unsigned int cmd_token_end = tokens_length;
+	
 	processed_pipes = 0;
 	
 	/* Check if the first part (from <file> |) is present */
-	if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) {
+	if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) {
 		/* Ignore the first three tokens (from, file, pipe) and set from */
-		redir_from = cmd[1];
-		actual_cmd = cmd + 3;
+		redir_from = tokens[2].text;
+		cmd_token_start = pipe_pos[0]+1;
+		printf("set cmd_token_start = %d\n", cmd_token_start);
 		processed_pipes++;
 	}
@@ -119,10 +132,12 @@
 	/* Check if the second part (| to <file>) is present */
 	if ((pipe_count - processed_pipes) > 0 &&
-	    pipe_pos[processed_pipes] == cmd_length - 3 &&
-	    str_cmp(cmd[cmd_length-2], "to") == 0) {
+	    (pipe_pos[processed_pipes] == tokens_length - 4 ||
+	    (pipe_pos[processed_pipes] == tokens_length - 5 &&
+	    tokens[tokens_length-4].type == TOKTYPE_SPACE )) &&
+	    str_cmp(tokens[tokens_length-3].text, "to") == 0) {
 		/* Ignore the last three tokens (pipe, to, file) and set to */
-		redir_to = cmd[cmd_length-1];
-		cmd[cmd_length-3] = NULL;
-		cmd_length -= 3;
+		redir_to = tokens[tokens_length-1].text;
+		cmd_token_end = pipe_pos[processed_pipes];
+		printf("set cmd_token_end = %d\n", cmd_token_end);
 		processed_pipes++;
 	}
@@ -134,5 +149,15 @@
 	}
 	
-	if (actual_cmd[0] == NULL) {
+	/* Convert tokens of the command to string array */
+	unsigned int cmd_pos = 0;
+	for (i = cmd_token_start; i < cmd_token_end; i++) {
+		if (tokens[i].type != TOKTYPE_SPACE) {
+			cmd[cmd_pos++] = tokens[i].text;
+			printf("%s\n", tokens[i].text);
+		}
+	}
+	cmd[cmd_pos++] = NULL;
+	
+	if (cmd[0] == NULL) {
 		print_pipe_usage();
 		rc = ENOTSUP;
@@ -170,5 +195,5 @@
 	}
 	
-	rc = run_command(actual_cmd, usr, &new_iostate);
+	rc = run_command(cmd, usr, &new_iostate);
 	
 finit_with_files:
Index: uspace/app/bdsh/tok.c
===================================================================
--- uspace/app/bdsh/tok.c	(revision 89660f22a2e2b7867763e40b0d9947f1df5622b3)
+++ uspace/app/bdsh/tok.c	(revision 0662451c35f4872031fe346116ad27f80b39296d)
@@ -42,4 +42,5 @@
 static bool tok_pending_chars(tokenizer_t *);
 static int tok_finish_string(tokenizer_t *);
+static void tok_start_token(tokenizer_t *, token_type_t);
 
 /** Initialize the token parser
@@ -61,7 +62,5 @@
 	tok->outtok = out_tokens;
 	tok->outtok_offset = 0;
-	/* Leave one slot for a null terminator */
-	assert(max_tokens > 0);
-	tok->outtok_size = max_tokens - 1;
+	tok->outtok_size = max_tokens;
 	
 	/* Prepare a buffer where all the token strings will be stored */
@@ -90,5 +89,5 @@
 
 /** Tokenize the input string into the tokens */
-int tok_tokenize(tokenizer_t *tok)
+int tok_tokenize(tokenizer_t *tok, size_t *tokens_length)
 {
 	int rc;
@@ -98,6 +97,5 @@
 	while ((cur_char = tok_get_char(tok)) != 0) {
 		if (cur_char == ' ') {
-			/* Spaces delimit tokens, but are not processed in any way
-			 * Push the token if there is any.
+			/* Push the token if there is any.
 			 * There may not be any pending char for a token in case
 			 * there are several spaces in the input.
@@ -109,4 +107,11 @@
 				}
 			}
+			tok_start_token(tok, TOKTYPE_SPACE);
+			/* Eat all spaces */
+			while (tok_look_char(tok) == ' ') {
+				tok_push_char(tok, tok_get_char(tok));
+			}
+			tok_push_token(tok);
+			
 		}
 		else if (cur_char == '|') {
@@ -121,4 +126,6 @@
 			}
 			
+			tok_start_token(tok, TOKTYPE_PIPE);
+			
 			rc = tok_push_char(tok, '|');
 			if (rc != EOK) {
@@ -135,4 +142,5 @@
 			 * A literal quote is written as ''
 			 */
+			tok_start_token(tok, TOKTYPE_TEXT);
 			rc = tok_finish_string(tok);
 			if (rc != EOK) {
@@ -141,4 +149,7 @@
 		}
 		else {
+			if (!tok_pending_chars(tok)) {
+				tok_start_token(tok, TOKTYPE_TEXT);
+			}
 			/* If we are handling any other character, just append it to
 			 * the current token.
@@ -159,7 +170,5 @@
 	}
 	
-	/* We always have a space for the terminator, as we
-	 * reserved it in tok_init */
-	tok->outtok[tok->outtok_offset] = 0;
+	*tokens_length = tok->outtok_offset;
 	
 	return EOK;
@@ -211,6 +220,6 @@
 wchar_t tok_look_char(tokenizer_t *tok)
 {
-	off_t old_offset = tok->in_offset;
-	off_t old_char_offset = tok->in_char_offset;
+	unsigned int old_offset = tok->in_offset;
+	unsigned int old_char_offset = tok->in_char_offset;
 	wchar_t ret = tok_get_char(tok);
 	tok->in_offset = old_offset;
@@ -225,4 +234,9 @@
 }
 
+void tok_start_token(tokenizer_t *tok, token_type_t type)
+{
+	tok->current_type = type;
+}
+
 /** Push the current token to the output array */
 int tok_push_token(tokenizer_t *tok)
@@ -237,12 +251,12 @@
 	
 	tok->outbuf[tok->outbuf_offset++] = 0;
-	token_t *tokinfo = &tok->outtok[tok->outtok_offset++]
-	tokinfo.text = tok->outbuf + tok->outbuf_last_start;
-	tokinfo.byte_start = tok->last_in_offset;
-	tokinfo.byte_length = tok->in_offset - tok->last_in_offset - 1;
-	tokinfo.char_start = tok->last_in_char_offset;
-	tokinfo.char_length = tok->in_char_offset - tok->last_in_char_offset
+	token_t *tokinfo = &tok->outtok[tok->outtok_offset++];
+	tokinfo->type = tok->current_type;
+	tokinfo->text = tok->outbuf + tok->outbuf_last_start;
+	tokinfo->byte_start = tok->last_in_offset;
+	tokinfo->byte_length = tok->in_offset - tok->last_in_offset - 1;
+	tokinfo->char_start = tok->last_in_char_offset;
+	tokinfo->char_length = tok->in_char_offset - tok->last_in_char_offset
 	    - 1;
-	tok->outtok[tok->outtok_offset]
 	tok->outbuf_last_start = tok->outbuf_offset;
 	
Index: uspace/app/bdsh/tok.h
===================================================================
--- uspace/app/bdsh/tok.h	(revision 89660f22a2e2b7867763e40b0d9947f1df5622b3)
+++ uspace/app/bdsh/tok.h	(revision 0662451c35f4872031fe346116ad27f80b39296d)
@@ -38,6 +38,6 @@
 typedef struct {
 	char *text;
-	off_t byte_start;
-	off_t char_start;
+	unsigned int byte_start;
+	unsigned int char_start;
 	size_t byte_length;
 	size_t char_length;
@@ -47,8 +47,8 @@
 typedef struct {
 	char *in;
-	off_t in_offset;
-	off_t last_in_offset;
-	off_t in_char_offset;
-	off_t last_in_char_offset;
+	unsigned int in_offset;
+	unsigned int last_in_offset;
+	unsigned int in_char_offset;
+	unsigned int last_in_char_offset;
 	
 	char *outbuf;
@@ -58,4 +58,5 @@
 	
 	token_t *outtok;
+	token_type_t current_type;
 	size_t outtok_offset;
 	size_t outtok_size;
@@ -64,5 +65,5 @@
 extern int tok_init(tokenizer_t *, char *, token_t *, size_t);
 extern void tok_fini(tokenizer_t *);
-extern int tok_tokenize(tokenizer_t *);
+extern int tok_tokenize(tokenizer_t *, size_t *);
 
 #endif
