diff --git a/src/shell/pipe_exec/mod.rs b/src/shell/pipe_exec/mod.rs
index 32852365cd0a509a9510fabcb75282c8857ff607..717b6328f483a98fbaf6cdfcd70f1fad1f31da6a 100644
--- a/src/shell/pipe_exec/mod.rs
+++ b/src/shell/pipe_exec/mod.rs
@@ -14,12 +14,13 @@ use super::flags::*;
 use super::job::RefinedJob;
 use super::signals::{self, SignalHandler};
 use super::status::*;
-use parser::peg::{Input, Pipeline, RedirectFrom};
+use parser::peg::{Input, Pipeline, Redirection, RedirectFrom};
 use std::fs::{File, OpenOptions};
 use std::io::{self, Error, Write};
 use std::iter;
 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
 use std::os::unix::process::CommandExt;
+use std::path::Path;
 use std::process::{exit, Command};
 use sys;
 
@@ -49,7 +50,7 @@ pub unsafe fn stdin_of<T: AsRef<[u8]>>(input: T) -> Result<RawFd, Error> {
 /// 1. If the result is `Some`, then we will fork the pipeline executing into the background.
 /// 2. The value stored within `Some` will be that background job's command name.
 /// 3. If `set -x` was set, print the command.
-fn check_if_background_job(pipeline: &Pipeline, print_comm: bool) -> Option<String> {
+fn gen_background_string(pipeline: &Pipeline, print_comm: bool) -> Option<String> {
     if pipeline.jobs[pipeline.jobs.len() - 1].kind == JobKind::Background {
         let command = pipeline.to_string();
         if print_comm {
@@ -64,101 +65,150 @@ fn check_if_background_job(pipeline: &Pipeline, print_comm: bool) -> Option<Stri
     }
 }
 
+/// Determines if the supplied command implicitly defines to change the directory.
+///
+/// This is detected by first checking if the argument starts with a '.' or an '/', or ends
+/// with a '/'. If that validates, then it will check if the supplied argument is a valid
+/// directory path.
 #[inline(always)]
 fn is_implicit_cd(argument: &str) -> bool {
-    argument.starts_with('.') || argument.starts_with('/') || argument.ends_with('/')
+    (argument.starts_with('.') || argument.starts_with('/') || argument.ends_with('/')) &&
+        Path::new(argument).is_dir()
 }
 
-pub trait PipelineExecution {
-    fn execute_pipeline(&mut self, pipeline: &mut Pipeline) -> i32;
+/// This function is to be executed when a stdin value is supplied to a pipeline job.
+///
+/// Using that value, the stdin of the first command will be mapped to either a `File`,
+/// or `HereString`, which may be either a herestring or heredoc.
+fn redirect_input(mut input: Input, piped_commands: &mut Vec<(RefinedJob, JobKind)>) {
+    match input {
+        Input::File(ref filename) => if let Some(command) = piped_commands.first_mut() {
+            match File::open(filename) {
+                Ok(file) => command.0.stdin(file),
+                Err(e) => eprintln!("ion: failed to redirect '{}' into stdin: {}", filename, e),
+            }
+        },
+        Input::HereString(ref mut string) => if let Some(command) = piped_commands.first_mut() {
+            if !string.ends_with('\n') {
+                string.push('\n');
+            }
+            match unsafe { stdin_of(&string) } {
+                Ok(stdio) => {
+                    command.0.stdin(unsafe { File::from_raw_fd(stdio) });
+                }
+                Err(e) => {
+                    eprintln!("ion: failed to redirect herestring '{}' into stdin: {}", string, e);
+                }
+            }
+        },
+    }
 }
 
-impl<'a> PipelineExecution for Shell<'a> {
-    fn execute_pipeline(&mut self, pipeline: &mut Pipeline) -> i32 {
-        let background_string = check_if_background_job(&pipeline, self.flags & PRINT_COMMS != 0);
-
-        let mut piped_commands: Vec<(RefinedJob, JobKind)> = {
-            pipeline
-                .jobs
-                .drain(..)
-                .map(|mut job| {
-                    let refined = {
-                        if is_implicit_cd(&job.args[0]) {
-                            RefinedJob::builtin("cd".into(), iter::once("cd".into()).chain(job.args.drain()).collect())
-                        } else if self.builtins.contains_key::<str>(job.command.as_ref()) {
-                            RefinedJob::builtin(job.command, job.args.drain().collect())
-                        } else {
-                            let mut command = Command::new(job.command);
-                            for arg in job.args.drain().skip(1) {
-                                command.arg(arg);
-                            }
-                            RefinedJob::External(command)
-                        }
-                    };
-                    (refined, job.kind)
-                })
-                .collect()
+/// This function is to be executed when a stdout/stderr value is supplied to a pipeline job.
+///
+/// Using that value, the stdout and/or stderr of the last command will be redirected accordingly
+/// to the designated output.
+fn redirect_output(stdout: Redirection, piped_commands: &mut Vec<(RefinedJob, JobKind)>) {
+    if let Some(mut command) = piped_commands.last_mut() {
+        let file = if stdout.append {
+            OpenOptions::new()
+                .create(true)
+                .write(true)
+                .append(true)
+                .open(&stdout.file)
+        } else {
+            File::create(&stdout.file)
         };
-        match pipeline.stdin {
-            None => (),
-            Some(Input::File(ref filename)) => if let Some(command) = piped_commands.first_mut() {
-                match File::open(filename) {
-                    Ok(file) => command.0.stdin(file),
-                    Err(e) => eprintln!("ion: failed to redirect '{}' into stdin: {}", filename, e),
-                }
-            },
-            Some(Input::HereString(ref mut string)) => if let Some(command) = piped_commands.first_mut() {
-                if !string.ends_with('\n') {
-                    string.push('\n');
-                }
-                match unsafe { stdin_of(&string) } {
-                    Ok(stdio) => {
-                        command.0.stdin(unsafe { File::from_raw_fd(stdio) });
+        match file {
+            Ok(f) => match stdout.from {
+                RedirectFrom::Both => match f.try_clone() {
+                    Ok(f_copy) => {
+                        command.0.stdout(f);
+                        command.0.stderr(f_copy);
                     }
                     Err(e) => {
-                        eprintln!("ion: failed to redirect herestring '{}' into stdin: {}", string, e);
+                        eprintln!("ion: failed to redirect both stderr and stdout into file '{:?}': {}", f, e);
                     }
-                }
+                },
+                RedirectFrom::Stderr => command.0.stderr(f),
+                RedirectFrom::Stdout => command.0.stdout(f),
             },
-        }
-
-        if let Some(ref stdout) = pipeline.stdout {
-            if let Some(mut command) = piped_commands.last_mut() {
-                let file = if stdout.append {
-                    OpenOptions::new()
-                        .create(true)
-                        .write(true)
-                        .append(true)
-                        .open(&stdout.file)
-                } else {
-                    File::create(&stdout.file)
-                };
-                match file {
-                    Ok(f) => match stdout.from {
-                        RedirectFrom::Both => match f.try_clone() {
-                            Ok(f_copy) => {
-                                command.0.stdout(f);
-                                command.0.stderr(f_copy);
-                            }
-                            Err(e) => {
-                                eprintln!("ion: failed to redirect both stderr and stdout into file '{:?}': {}", f, e);
-                            }
-                        },
-                        RedirectFrom::Stderr => command.0.stderr(f),
-                        RedirectFrom::Stdout => command.0.stdout(f),
-                    },
-                    Err(err) => {
-                        let stderr = io::stderr();
-                        let mut stderr = stderr.lock();
-                        let _ = writeln!(stderr, "ion: failed to redirect stdout into {}: {}", stdout.file, err);
-                    }
-                }
+            Err(err) => {
+                let stderr = io::stderr();
+                let mut stderr = stderr.lock();
+                let _ = writeln!(stderr, "ion: failed to redirect stdout into {}: {}", stdout.file, err);
             }
         }
+    }
+}
+
+pub trait PipelineExecution {
+    /// Given a pipeline, generates commands and executes them.
+    ///
+    /// The `Pipeline` structure contains a vector of `Job`s, and redirections to perform on the
+    /// pipeline. Executing a pipeline involves creating a vector of commands, of which each
+    /// command may refer to either a builtin command, or an external command. These commands
+    /// will then be sent to an internal `pipe` function for execution.
+    ///
+    /// Depending on which operators are supplied, jobs may conditionally execute, pipe their
+    /// outputs to adjacent jobs in the pipeline, or execute in the background. To enable job
+    /// control, these jobs will also be assigned to their own unique process groups, may be
+    /// given foreground terminal access, and will be monitored for status changes in the event
+    /// that a job was signaled to stop or killed.
+    ///
+    /// If a job is stopped, the shell will add that job to a list of background jobs and continue
+    /// to watch the job in the background, printing notifications on status changes of that job
+    /// over time.
+    fn execute_pipeline(&mut self, pipeline: &mut Pipeline) -> i32;
+
+    /// Generates a vector of commands from a given `Pipeline`.
+    ///
+    /// Each generated command will either be a builtin or external command, and will be
+    /// associated will be marked as an `&&`, `||`, `|`, or final job.
+    fn generate_commands(&self, pipeline: &mut Pipeline) -> Vec<(RefinedJob, JobKind)>;
 
+    /// Waits for all of the children within a pipe to finish exuecting, returning the
+    /// exit status of the last process in the queue.
+    fn wait(&mut self, children: Vec<u32>, commands: Vec<RefinedJob>) -> i32;
+
+    /// Executes a `RefinedJob` that was created in the `generate_commands` method.
+    ///
+    /// The aforementioned `RefinedJob` may be either a builtin or external command.
+    /// The purpose of this function is therefore to execute both types accordingly.
+    fn exec_job(&mut self, job: &mut RefinedJob, foreground: bool) -> i32;
+
+    /// Execute a builtin in the current process.
+    /// # Args
+    /// * `shell`: A `Shell` that forwards relevant information to the builtin
+    /// * `name`: Name of the builtin to execute.
+    /// * `stdin`, `stdout`, `stderr`: File descriptors that will replace the
+    ///    respective standard streams if they are not `None`
+    /// # Preconditions
+    /// * `shell.builtins.contains_key(name)`; otherwise this function will panic
+    fn exec_builtin(
+        &mut self,
+        name: &str,
+        args: &[&str],
+        stdout: &Option<File>,
+        stderr: &Option<File>,
+        stdin: &Option<File>,
+    ) -> i32;
+}
+
+impl<'a> PipelineExecution for Shell<'a> {
+    fn execute_pipeline(&mut self, pipeline: &mut Pipeline) -> i32 {
+        // Remove any leftover foreground tasks from the last execution.
         self.foreground.clear();
+        // If the supplied pipeline is a background, a string representing the command will be stored here.
+        let possible_background_name = gen_background_string(&pipeline, self.flags & PRINT_COMMS != 0);
+        // Generates commands for execution, differentiating between external and builtin commands.
+        let mut piped_commands = self.generate_commands(pipeline);
+        // Redirect the inputs if a custom redirect value was given.
+        if let Some(stdin) = pipeline.stdin.take() { redirect_input(stdin, &mut piped_commands); }
+        // Redirect the outputs if a custom redirect value was given.
+        if let Some(stdout) = pipeline.stdout.take() { redirect_output(stdout, &mut piped_commands); }
         // If the given pipeline is a background task, fork the shell.
-        if let Some(command_name) = background_string {
+        if let Some(command_name) = possible_background_name {
             fork_pipe(self, piped_commands, command_name)
         } else {
             // While active, the SIGTTOU signal will be ignored.
@@ -170,6 +220,134 @@ impl<'a> PipelineExecution for Shell<'a> {
             exit_status
         }
     }
+
+    fn generate_commands(&self, pipeline: &mut Pipeline) -> Vec<(RefinedJob, JobKind)> {
+        pipeline
+            .jobs
+            .drain(..)
+            .map(|mut job| {
+                let refined = {
+                    if is_implicit_cd(&job.args[0]) {
+                        RefinedJob::builtin("cd".into(), iter::once("cd".into()).chain(job.args.drain()).collect())
+                    } else if self.builtins.contains_key::<str>(job.command.as_ref()) {
+                        RefinedJob::builtin(job.command, job.args.drain().collect())
+                    } else {
+                        let mut command = Command::new(job.command);
+                        for arg in job.args.drain().skip(1) {
+                            command.arg(arg);
+                        }
+                        RefinedJob::External(command)
+                    }
+                };
+                (refined, job.kind)
+            })
+            .collect()
+    }
+
+    fn wait(&mut self, mut children: Vec<u32>, mut commands: Vec<RefinedJob>) -> i32 {
+        // TODO: Find a way to only do this when absolutely necessary.
+        let as_string = commands
+            .iter()
+            .map(RefinedJob::long)
+            .collect::<Vec<String>>()
+            .join(" | ");
+
+        // Each process in the pipe has the same PGID, which is the first process's PID.
+        let pgid = children[0];
+
+        // If the last process exits, we know that all processes should exit.
+        let last_pid = children[children.len() - 1];
+
+        // Watch the foreground group, dropping all commands that exit as they exit.
+        self.watch_foreground(
+            pgid,
+            last_pid,
+            move || as_string,
+            move |pid| if let Some(id) = children.iter().position(|&x| x as i32 == pid) {
+                commands.remove(id);
+                children.remove(id);
+            },
+        )
+    }
+
+    fn exec_job(&mut self, job: &mut RefinedJob, foreground: bool) -> i32 {
+        let short = job.short();
+        let long = job.long();
+        match *job {
+            RefinedJob::External(ref mut command) => match {
+                command
+                    .before_exec(move || {
+                        signals::unblock();
+                        create_process_group(0);
+                        Ok(())
+                    })
+                    .spawn()
+            } {
+                Ok(child) => {
+                    if foreground {
+                        let _ = sys::tcsetpgrp(0, child.id());
+                    }
+                    self.watch_foreground(child.id(), child.id(), move || long, |_| ())
+                }
+                Err(e) => {
+                    if e.kind() == io::ErrorKind::NotFound {
+                        eprintln!("ion: command not found: {}", short);
+                        NO_SUCH_COMMAND
+                    } else {
+                        eprintln!("ion: error spawning process: {}", e);
+                        COULD_NOT_EXEC
+                    }
+                }
+            },
+            RefinedJob::Builtin {
+                ref name,
+                ref args,
+                ref stdin,
+                ref stdout,
+                ref stderr,
+            } => {
+                if let Ok(stdout_bk) = sys::dup(sys::STDOUT_FILENO) {
+                    if let Ok(stderr_bk) = sys::dup(sys::STDERR_FILENO) {
+                        if let Ok(stdin_bk) = sys::dup(sys::STDIN_FILENO) {
+                            let args: Vec<&str> = args.iter().map(|x| x as &str).collect();
+                            let code = self.exec_builtin(name, &args, stdout, stderr, stdin);
+                            redir(stdout_bk, sys::STDOUT_FILENO);
+                            redir(stderr_bk, sys::STDERR_FILENO);
+                            redir(stdin_bk, sys::STDIN_FILENO);
+                            return code;
+                        }
+                        let _ = sys::close(stderr_bk);
+                    }
+                    let _ = sys::close(stdout_bk);
+                }
+                eprintln!("ion: failed to `dup` STDOUT, STDIN, or STDERR: not running '{}'", long);
+                FAILURE
+            }
+        }
+    }
+
+    fn exec_builtin(
+        &mut self,
+        name: &str,
+        args: &[&str],
+        stdout: &Option<File>,
+        stderr: &Option<File>,
+        stdin: &Option<File>,
+    ) -> i32 {
+        if let Some(ref file) = *stdin {
+            redir(file.as_raw_fd(), sys::STDIN_FILENO);
+        }
+        if let Some(ref file) = *stdout {
+            redir(file.as_raw_fd(), sys::STDOUT_FILENO);
+        }
+        if let Some(ref file) = *stderr {
+            redir(file.as_raw_fd(), sys::STDERR_FILENO);
+        }
+        // The precondition for this function asserts that there exists some `builtin`
+        // in the shell named `name`, so we unwrap here.
+        let builtin = self.builtins.get(name).unwrap();
+        (builtin.main)(args, self)
+    }
 }
 
 /// This function will panic if called with an empty slice
@@ -267,8 +445,7 @@ pub fn pipe(shell: &mut Shell, commands: Vec<(RefinedJob, JobKind)>, foreground:
                                             let args: Vec<&str> = args
                                                 .iter()
                                                 .map(|x| x as &str).collect();
-                                            let ret = builtin(shell,
-                                                              name,
+                                            let ret = shell.exec_builtin(name,
                                                               &args,
                                                               stdout,
                                                               stderr,
@@ -347,14 +524,14 @@ pub fn pipe(shell: &mut Shell, commands: Vec<(RefinedJob, JobKind)>, foreground:
                         }
                     }
                     previous_kind = kind;
-                    previous_status = wait(shell, children, remember);
+                    previous_status = shell.wait(children, remember);
                     if previous_status == TERMINATED {
                         shell.foreground_send(sys::SIGTERM);
                         return previous_status;
                     }
                 }
                 _ => {
-                    previous_status = execute(shell, &mut parent, foreground);
+                    previous_status = shell.exec_job(&mut parent, foreground);
                     previous_kind = kind;
                 }
             }
@@ -364,119 +541,3 @@ pub fn pipe(shell: &mut Shell, commands: Vec<(RefinedJob, JobKind)>, foreground:
     }
     previous_status
 }
-
-fn execute(shell: &mut Shell, job: &mut RefinedJob, foreground: bool) -> i32 {
-    let short = job.short();
-    let long = job.long();
-    match *job {
-        RefinedJob::External(ref mut command) => match {
-            command
-                .before_exec(move || {
-                    signals::unblock();
-                    create_process_group(0);
-                    Ok(())
-                })
-                .spawn()
-        } {
-            Ok(child) => {
-                if foreground {
-                    let _ = sys::tcsetpgrp(0, child.id());
-                }
-                shell.watch_foreground(child.id(), child.id(), move || long, |_| ())
-            }
-            Err(e) => {
-                if e.kind() == io::ErrorKind::NotFound {
-                    eprintln!("ion: command not found: {}", short);
-                    NO_SUCH_COMMAND
-                } else {
-                    eprintln!("ion: error spawning process: {}", e);
-                    COULD_NOT_EXEC
-                }
-            }
-        },
-        RefinedJob::Builtin {
-            ref name,
-            ref args,
-            ref stdin,
-            ref stdout,
-            ref stderr,
-        } => {
-            if let Ok(stdout_bk) = sys::dup(sys::STDOUT_FILENO) {
-                if let Ok(stderr_bk) = sys::dup(sys::STDERR_FILENO) {
-                    if let Ok(stdin_bk) = sys::dup(sys::STDIN_FILENO) {
-                        let args: Vec<&str> = args.iter().map(|x| x as &str).collect();
-                        let code = builtin(shell, name, &args, stdout, stderr, stdin);
-                        redir(stdout_bk, sys::STDOUT_FILENO);
-                        redir(stderr_bk, sys::STDERR_FILENO);
-                        redir(stdin_bk, sys::STDIN_FILENO);
-                        return code;
-                    }
-                    let _ = sys::close(stderr_bk);
-                }
-                let _ = sys::close(stdout_bk);
-            }
-            eprintln!("ion: failed to `dup` STDOUT, STDIN, or STDERR: not running '{}'", long);
-            FAILURE
-        }
-    }
-}
-
-/// Waits for all of the children within a pipe to finish exuecting, returning the
-/// exit status of the last process in the queue.
-fn wait(shell: &mut Shell, mut children: Vec<u32>, mut commands: Vec<RefinedJob>) -> i32 {
-    // TODO: Find a way to only do this when absolutely necessary.
-    let as_string = commands
-        .iter()
-        .map(RefinedJob::long)
-        .collect::<Vec<String>>()
-        .join(" | ");
-
-    // Each process in the pipe has the same PGID, which is the first process's PID.
-    let pgid = children[0];
-
-    // If the last process exits, we know that all processes should exit.
-    let last_pid = children[children.len() - 1];
-
-    // Watch the foreground group, dropping all commands that exit as they exit.
-    shell.watch_foreground(
-        pgid,
-        last_pid,
-        move || as_string,
-        move |pid| if let Some(id) = children.iter().position(|&x| x as i32 == pid) {
-            commands.remove(id);
-            children.remove(id);
-        },
-    )
-}
-
-
-/// Execute a builtin in the current process.
-/// # Args
-/// * `shell`: A `Shell` that forwards relevant information to the builtin
-/// * `name`: Name of the builtin to execute.
-/// * `stdin`, `stdout`, `stderr`: File descriptors that will replace the
-///    respective standard streams if they are not `None`
-/// # Preconditions
-/// * `shell.builtins.contains_key(name)`; otherwise this function will panic
-fn builtin(
-    shell: &mut Shell,
-    name: &str,
-    args: &[&str],
-    stdout: &Option<File>,
-    stderr: &Option<File>,
-    stdin: &Option<File>,
-) -> i32 {
-    if let Some(ref file) = *stdin {
-        redir(file.as_raw_fd(), sys::STDIN_FILENO);
-    }
-    if let Some(ref file) = *stdout {
-        redir(file.as_raw_fd(), sys::STDOUT_FILENO);
-    }
-    if let Some(ref file) = *stderr {
-        redir(file.as_raw_fd(), sys::STDERR_FILENO);
-    }
-    // The precondition for this function asserts that there exists some `builtin`
-    // in `shell` named `name`, so we unwrap here
-    let builtin = shell.builtins.get(name).unwrap();
-    (builtin.main)(args, shell)
-}