diff --git a/Assignment-05/starter/dsh b/Assignment-05/starter/dsh
new file mode 100755
index 0000000000000000000000000000000000000000..d9bbee0f94d14b88ce2b9fb8aeccce18ea7b2709
Binary files /dev/null and b/Assignment-05/starter/dsh differ
diff --git a/Assignment-05/starter/dshlib.c b/Assignment-05/starter/dshlib.c
index a21bbe118fc2e9a07dbce69cd35702cf72f86fe0..cda615e4041620fc409f812571fedcf6ac5ea930 100644
--- a/Assignment-05/starter/dshlib.c
+++ b/Assignment-05/starter/dshlib.c
@@ -9,6 +9,16 @@
 
 #include "dshlib.h"
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include "dshlib.h"
+
+//
 int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff) {
     if (cmd_line == NULL || cmd_buff == NULL) {
         return ERR_CMD_OR_ARGS_TOO_BIG;
@@ -19,175 +29,194 @@ int build_cmd_buff(char *cmd_line, cmd_buff_t *cmd_buff) {
         return ERR_MEMORY;
     }
 
-    char *trimmed_line = original_line;
-    while (*trimmed_line == ' ') {
-        trimmed_line++;
-    }
-
-    size_t len = strlen(trimmed_line);
-    while (len > 0 && trimmed_line[len - 1] == ' ') {
-        trimmed_line[--len] = '\0';
-    }
-
     cmd_buff->argc = 0;
     cmd_buff->_cmd_buffer = original_line;
 
-    char *saveptr1;
-    char *token = strtok_r(trimmed_line, " ", &saveptr1);
-
-    while (token != NULL && cmd_buff->argc < CMD_ARGV_MAX) {
-        if (token[0] == '"' || token[0] == '\'') {
-            char *end_quote = strchr(token + 1, token[0]);
-            if (end_quote != NULL) {
-                *end_quote = '\0';
-                cmd_buff->argv[cmd_buff->argc++] = token + 1;
-                token = strtok_r(NULL, " ", &saveptr1);
-                continue;
+    char *ptr = original_line;
+    char *arg_start = NULL;
+    bool in_quotes = false;//For quotes 
+    char quote_char = '\0';
+
+    while (*ptr != '\0') {
+        if ((isspace((unsigned char)*ptr) && !in_quotes)) {
+            if (arg_start != NULL) {
+                *ptr = '\0';
+                cmd_buff->argv[cmd_buff->argc++] = arg_start;
+                arg_start = NULL;
+            }
+        } else if (*ptr == '"' || *ptr == '\'') {
+            if (in_quotes && *ptr == quote_char) {
+                in_quotes = false;
+                quote_char = '\0';
+                *ptr = '\0';  // End the argument at the closing quote
+            } else if (!in_quotes) {
+                in_quotes = true;
+                quote_char = *ptr;
+                arg_start = ptr + 1;  // Start the argument after the opening quote
+            }
+        } else {
+            if (arg_start == NULL) {
+                arg_start = ptr;
             }
         }
-        cmd_buff->argv[cmd_buff->argc++] = token;
-        token = strtok_r(NULL, " ", &saveptr1);
+        ptr++;
     }
+
+    if (arg_start != NULL) {
+        cmd_buff->argv[cmd_buff->argc++] = arg_start;
+    }
+
     cmd_buff->argv[cmd_buff->argc] = NULL;
 
-    return OK;
-}
+	 // Debugging output to verify parsing
+	 // printf("Parsed command:\n");
+	 // for (int i = 0; i < cmd_buff->argc; i++) {
+	 //     printf("  argv[%d]: %s\n", i, cmd_buff->argv[i]);
+	 // }
 
 
-int execute_pipeline(command_list_t *cmd_list) {
-    int num_commands = cmd_list->num;
-    int pipefd[2];
-    int prev_pipe_read = -1;
-    pid_t pids[num_commands];
 
-    for (int i = 0; i < num_commands; i++) {
-        if (i < num_commands - 1) {
-            if (pipe(pipefd) == -1) {
-                perror("pipe");
-                return ERR_MEMORY;
-            }
-        }
+    return OK;
+}
 
-        pids[i] = fork();
-        if (pids[i] == -1) {
-            perror("fork");
-            return ERR_MEMORY;
-        }
+char *trim_whitespace(char *str) { //Had to make a new function for readability
+    char *end;
 
-        if (pids[i] == 0) {
-            if (prev_pipe_read != -1) {
-                dup2(prev_pipe_read, STDIN_FILENO);
-                close(prev_pipe_read);
-            }
+    while (isspace((unsigned char)*str)) str++;
 
-            if (i < num_commands - 1) {
-                dup2(pipefd[1], STDOUT_FILENO);
-                close(pipefd[1]);
-                close(pipefd[0]);
-            }
+    if (*str == 0)  // All spaces?
+        return str;
 
-            if (prev_pipe_read != -1) {
-                close(prev_pipe_read);
-            }
+    // Trim trailing space
+    end = str + strlen(str) - 1;
+    while (end > str && isspace((unsigned char)*end)) end--;
 
-            cmd_buff_t *cmd = &cmd_list->commands[i];
+    // new null terminator
+    *(end + 1) = '\0';
 
-            if (cmd->argv[0] == NULL) {
-                fprintf(stderr, "execvp error: command is NULL\n");
-                exit(ERR_EXEC_CMD);
-            }
+    return str;
+}
 
-            execvp(cmd->argv[0], cmd->argv);
 
-            perror("execvp");
-            exit(ERR_EXEC_CMD);
-        } else { 
-            if (prev_pipe_read != -1) {
-                close(prev_pipe_read);
-            }
 
-            if (i < num_commands - 1) {
-                prev_pipe_read = pipefd[0];
-                close(pipefd[1]);
-            }
-        }
+
+int parse_pipeline(const char *cmd_line, command_list_t *clist) {
+    if (cmd_line == NULL || clist == NULL) {
+        return ERR_CMD_OR_ARGS_TOO_BIG;
     }
 
-    if (prev_pipe_read != -1) {
-        char buffer[1024];
-        ssize_t bytes_read;
-        while ((bytes_read = read(prev_pipe_read, buffer, sizeof(buffer) - 1)) > 0) {
-            buffer[bytes_read] = '\0';
-            printf("%s", buffer);
+    char *line_copy = strdup(cmd_line);
+    if (line_copy == NULL) {
+        return ERR_MEMORY;
+    }
+	 //Parsing using pipe.
+    clist->num = 0;
+    char *saveptr;
+    char *command = strtok_r(line_copy, "|", &saveptr);
+
+    while (command != NULL) {
+        if (clist->num >= CMD_MAX) {
+            free(line_copy);
+            return ERR_TOO_MANY_COMMANDS;
         }
-        if (bytes_read < 0) {
-            perror("read");
+
+        cmd_buff_t *cmd_buff = &clist->commands[clist->num];
+        int result = build_cmd_buff(command, cmd_buff);
+        if (result != OK) {
+            free(line_copy);
+            return result;
         }
-        close(prev_pipe_read);
-    }
 
-    for (int i = 0; i < num_commands; i++) {
-        waitpid(pids[i], NULL, 0);
+        clist->num++;
+        command = strtok_r(NULL, "|", &saveptr);
     }
 
+    free(line_copy);
     return OK;
 }
 
 
 
+int execute_pipeline(command_list_t *clist) {
+    int num_commands = clist->num;
+    int pipefd[2 * (num_commands - 1)];
+    pid_t pids[num_commands];
+	 
+	 // for (int i = 0; i < clist->num; i++) {
+    //     printf("Command %d:\n", i);
+	 //     for (int j = 0; clist->commands[i].argv[j] != NULL; j++) {
+	 //         printf("  argv[%d]: %s\n", j, clist->commands[i].argv[j]);
+	 //     }
+	 // }
 
 
-int parse_pipeline(char *cmd_line, command_list_t *clist) {
-    if (cmd_line == NULL || clist == NULL) {
-        return ERR_CMD_OR_ARGS_TOO_BIG;
-    }
 
-    char *original_line = strdup(cmd_line);
-    if (original_line == NULL) {
-        return ERR_MEMORY;
-    }
 
-    char *trimmed_line = original_line;
-    while (*trimmed_line == ' ') {
-        trimmed_line++;
-    }
-    size_t len = strlen(trimmed_line);
-    while (len > 0 && trimmed_line[len - 1] == ' ') {
-        trimmed_line[--len] = '\0';
+    for (int i = 0; i < num_commands - 1; i++) {
+        if (pipe(pipefd + 2 * i) == -1) {
+            perror("pipe");
+            return ERR_MEMORY;
+        }
     }
 
-    int command_count = 0;
-    char *saveptr1, *saveptr2;
-    char *command = strtok_r(trimmed_line, PIPE_STRING, &saveptr1);
+    // Fork processes for each command
+    for (int i = 0; i < num_commands; i++) {
+        pids[i] = fork();
+        if (pids[i] == -1) {
+            perror("fork");
+            return ERR_MEMORY;
+        }
+
+        if (pids[i] == 0) {  // Child process
+            // if not first moves input
+            if (i > 0) {
+                if (dup2(pipefd[2 * (i - 1)], STDIN_FILENO) == -1) {
+                    perror("dup2 stdin");
+                    exit(EXIT_FAILURE);
+                }
+            }
 
-    while (command != NULL && command_count < CMD_MAX) {
-        memset(&clist->commands[command_count], 0, sizeof(cmd_buff_t));
+            // Redirect output if not the last command
+            if (i < num_commands - 1) {
+                if (dup2(pipefd[2 * i + 1], STDOUT_FILENO) == -1) {
+                    perror("dup2 stdout");
+                    exit(EXIT_FAILURE);
+                }
+            }
 
-        char *token = strtok_r(command, " ", &saveptr2);
-        if (token != NULL) {
-            int arg_count = 0;
-            while (token != NULL && arg_count < CMD_ARGV_MAX - 1) {
-                clist->commands[command_count].argv[arg_count] = token;
-                arg_count++;
-                token = strtok_r(NULL, " ", &saveptr2);
+            // Close all pipe file descriptors. Very important stuff
+            for (int j = 0; j < 2 * (num_commands - 1); j++) {
+                close(pipefd[j]);
             }
-            clist->commands[command_count].argv[arg_count] = NULL; 
+
+            // Execute the command
+            execvp(clist->commands[i].argv[0], clist->commands[i].argv);
+            perror("execvp");
+            exit(EXIT_FAILURE);
         }
+    }
 
-        command_count++;
-        command = strtok_r(NULL, PIPE_STRING, &saveptr1); 
+    // Closes all pipe
+    for (int i = 0; i < 2 * (num_commands - 1); i++) {
+        close(pipefd[i]);
     }
 
-    if (command != NULL) {
-        free(original_line);
-        return ERR_TOO_MANY_COMMANDS;
+    // waitpid so everyhting is smooth
+    for (int i = 0; i < num_commands; i++) {
+        int status;
+        waitpid(pids[i], &status, 0);
+        if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
+            fprintf(stderr, "Command %d exited with status %d\n", i, WEXITSTATUS(status));
+        } else if (WIFSIGNALED(status)) {
+            fprintf(stderr, "Command %d terminated by signal %d\n", i, WTERMSIG(status));
+        }
     }
 
-    clist->num = command_count;
-    free(original_line); 
     return OK;
 }
 
+
+
 int exec_local_cmd_loop() {
     char cmd_buff[SH_CMD_MAX];
     int rc = OK;
@@ -197,7 +226,7 @@ int exec_local_cmd_loop() {
 
         if (fgets(cmd_buff, SH_CMD_MAX, stdin) == NULL) {
             printf("\n");
-            break; 
+            break;
         }
 
         cmd_buff[strcspn(cmd_buff, "\n")] = '\0';
@@ -216,11 +245,11 @@ int exec_local_cmd_loop() {
                 continue;
             }
 
-            if (execute_pipeline(&cmd_list) != OK) {
-                fprintf(stderr, "%s\n", CMD_ERR_PIPE_LIMIT);
-                rc = ERR_MEMORY;
-            }
+            // Execute the pipeline
+
+            execute_pipeline(&cmd_list);
 
+            // Free memory for each command's buffer
             for (int i = 0; i < cmd_list.num; i++) {
                 free(cmd_list.commands[i]._cmd_buffer);
             }
@@ -233,8 +262,8 @@ int exec_local_cmd_loop() {
             }
 
             if (strcmp(cmd.argv[0], EXIT_CMD) == 0) {
-                free(cmd._cmd_buffer); 
-                break; 
+                free(cmd._cmd_buffer);
+                break;
             }
 
             if (strcmp(cmd.argv[0], "cd") == 0) {
@@ -258,7 +287,7 @@ int exec_local_cmd_loop() {
             } else if (pid == 0) {
                 execvp(cmd.argv[0], cmd.argv);
                 perror("execvp failed");
-                exit(EXIT_FAILURE); 
+                exit(EXIT_FAILURE);
             } else {
                 int status;
                 wait(&status);
@@ -276,3 +305,4 @@ int exec_local_cmd_loop() {
 
     return rc;
 }
+
diff --git a/Assignment-05/starter/dshlib.h b/Assignment-05/starter/dshlib.h
index fe3b24680bed23840340d37a89310125ae517306..0f949dcfd6284795a93293c206215d78a32ac94a 100644
--- a/Assignment-05/starter/dshlib.h
+++ b/Assignment-05/starter/dshlib.h
@@ -90,4 +90,4 @@ int execute_pipeline(command_list_t *clist);
 #define CMD_WARN_NO_CMD     "warning: no commands provided\n"
 #define CMD_ERR_PIPE_LIMIT  "error: piping limited to %d commands\n"
 
-#endif
\ No newline at end of file
+#endif
diff --git a/Assignment-05/starter/student_tests.sh b/Assignment-05/starter/student_tests.sh
index 638bc341446f7580a80c2aff52971b8023407ea8..6047b4a77d0910700dfb77987077a9fd3fcbbc67 100644
--- a/Assignment-05/starter/student_tests.sh
+++ b/Assignment-05/starter/student_tests.sh
@@ -4,11 +4,53 @@
 # 
 # Create your unit tests suit in this file
 
-@test "Example: check ls runs without errors" {
-    run ./dsh <<EOF                
-ls
+
+# Test pipeline: 'echo' output piped to 'grep'
+@test "Test echo output piped to grep" {
+    run ./dsh <<EOF
+echo "Hello World" | grep "World"
+exit
+EOF
+
+    # Assertions
+    [ "$status" -eq 0 ]
+    [[ "$output" == *"Hello World"* ]]
+}
+
+# Test pipeline with multiple commands: 'ls' piped to 'grep' and then to 'wc -l'
+@test "Test ls piped to grep and wc -l" {
+    run ./dsh <<EOF
+ls | grep "student_tests.sh" | wc -l
+exit
+EOF
+
+    # Assertions
+    [ "$status" -eq 0 ]
+    [[ "$output" -eq 1 ]]
+}
+
+# Test redirection: output of 'echo' redirected to a file
+@test "Test output redirection to a file" {
+    run ./dsh <<EOF
+echo "Test Output" > test_output.txt
+cat test_output.txt
+exit
+EOF
+
+    # Assertions
+    [ "$status" -eq 0 ]
+    [[ "$output" == *"Test Output"* ]]
+}
+
+# Test background execution: 'sleep' command in the background
+@test "Test background execution of sleep command" {
+    run ./dsh <<EOF
+sleep 2 &
+jobs
+exit
 EOF
 
     # Assertions
     [ "$status" -eq 0 ]
+    [[ "$output" == *"sleep 2 &"* ]]
 }