diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs
index 3bff5819c0c08322629362b4466f39da8ff92aeb..5afa92bae5edc0743abc21b7163b112511bfd858 100644
--- a/src/lib/shell/assignments.rs
+++ b/src/lib/shell/assignments.rs
@@ -46,9 +46,9 @@ fn list_vars(shell: &Shell) -> Result<(), io::Error> {
 /// exporting variables to some global environment
 pub(crate) trait VariableStore {
     /// Set a local variable given a binding
-    fn local(&mut self, action: LocalAction) -> i32;
+    fn local(&mut self, action: &LocalAction) -> i32;
     /// Export a variable to the process environment given a binding
-    fn export(&mut self, action: ExportAction) -> i32;
+    fn export(&mut self, action: &ExportAction) -> i32;
     /// Collect all updates to perform on variables for a given assignement action
     fn calculate<'a>(
         &mut self,
@@ -57,10 +57,10 @@ pub(crate) trait VariableStore {
 }
 
 impl VariableStore for Shell {
-    fn export(&mut self, action: ExportAction) -> i32 {
+    fn export(&mut self, action: &ExportAction) -> i32 {
         match action {
             ExportAction::Assign(ref keys, op, ref vals) => {
-                let actions = AssignmentActions::new(keys, op, vals);
+                let actions = AssignmentActions::new(keys, *op, vals);
 
                 for action in actions {
                     let err = action.map_err(|e| e.to_string()).and_then(|act| {
@@ -181,14 +181,14 @@ impl VariableStore for Shell {
         Ok(backup)
     }
 
-    fn local(&mut self, action: LocalAction) -> i32 {
+    fn local(&mut self, action: &LocalAction) -> i32 {
         match action {
             LocalAction::List => {
                 let _ = list_vars(&self);
                 SUCCESS
             }
             LocalAction::Assign(ref keys, op, ref vals) => {
-                let actions = AssignmentActions::new(keys, op, vals);
+                let actions = AssignmentActions::new(keys, *op, vals);
                 if let Err(why) = self.calculate(actions).and_then(|apply| {
                     for (key, value) in apply {
                         self.assign(&key, value)?
diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs
index c0fc0e71c0060992da008bc4650f34540d0086f3..4fff77e3869f6eaae20fb6d4f61dc1351d078d41 100644
--- a/src/lib/shell/flow.rs
+++ b/src/lib/shell/flow.rs
@@ -18,19 +18,8 @@ use crate::{
 };
 use itertools::Itertools;
 use small;
-use std::io::{stdout, Write};
-
-macro_rules! handle_signal {
-    ($signal:expr) => {
-        match $signal {
-            Condition::Break => break,
-            Condition::SigInt => return Condition::SigInt,
-            _ => (),
-        }
-    };
-}
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
 pub(crate) enum Condition {
     Continue,
     Break,
@@ -44,11 +33,7 @@ pub(crate) trait FlowLogic {
 
     /// Executes all of the statements within a while block until a certain
     /// condition is met.
-    fn execute_while(
-        &mut self,
-        expression: Vec<Statement>,
-        statements: Vec<Statement>,
-    ) -> Condition;
+    fn execute_while(&mut self, expression: &[Statement], statements: &[Statement]) -> Condition;
 
     /// Executes all of the statements within a for block for each value
     /// specified in the range.
@@ -56,67 +41,65 @@ pub(crate) trait FlowLogic {
         &mut self,
         variables: &[types::Str],
         values: &[small::String],
-        statements: Vec<Statement>,
+        statements: &[Statement],
     ) -> Condition;
 
     /// Conditionally executes branches of statements according to evaluated
     /// expressions
     fn execute_if(
         &mut self,
-        expression: Vec<Statement>,
-        success: Vec<Statement>,
-        else_if: Vec<ElseIf>,
-        failure: Vec<Statement>,
+        expression: &[Statement],
+        success: &[Statement],
+        else_if: &[ElseIf],
+        failure: &[Statement],
     ) -> Condition;
 
     /// Simply executes all supplied statements.
-    fn execute_statements(&mut self, statements: Vec<Statement>) -> Condition;
+    fn execute_statements(&mut self, statements: &[Statement]) -> Condition;
 
     /// Executes a single statement
-    fn execute_statement(&mut self, statement: Statement) -> Condition;
+    fn execute_statement(&mut self, statement: &Statement) -> Condition;
 
     /// Expand an expression and run a branch based on the value of the
     /// expanded expression
-    fn execute_match(&mut self, expression: small::String, cases: Vec<Case>) -> Condition;
+    fn execute_match<T: AsRef<str>>(&mut self, expression: T, cases: &[Case]) -> Condition;
 }
 
 impl FlowLogic for Shell {
     fn execute_if(
         &mut self,
-        expression: Vec<Statement>,
-        success: Vec<Statement>,
-        else_if: Vec<ElseIf>,
-        failure: Vec<Statement>,
+        expression: &[Statement],
+        success: &[Statement],
+        else_if: &[ElseIf],
+        failure: &[Statement],
     ) -> Condition {
         // Try execute success branch
-        if let Condition::SigInt = self.execute_statements(expression) {
+        if let Condition::SigInt = self.execute_statements(&expression) {
             return Condition::SigInt;
         }
         if self.previous_status == 0 {
-            return self.execute_statements(success);
+            return self.execute_statements(&success);
         }
 
         // Try to execute else_if branches
-        let else_if_conditions = else_if.into_iter().map(|cond| (cond.expression, cond.success));
-
-        for (condition, statements) in else_if_conditions {
-            if let Condition::SigInt = self.execute_statements(condition) {
+        for ElseIf { expression, success } in else_if {
+            if let Condition::SigInt = self.execute_statements(&expression) {
                 return Condition::SigInt;
             }
 
             if self.previous_status == 0 {
-                return self.execute_statements(statements);
+                return self.execute_statements(&success);
             }
         }
 
-        self.execute_statements(failure)
+        self.execute_statements(&failure)
     }
 
     fn execute_for(
         &mut self,
         variables: &[types::Str],
         values: &[small::String],
-        statements: Vec<Statement>,
+        statements: &[Statement],
     ) -> Condition {
         macro_rules! set_vars_then_exec {
             ($chunk:expr, $def:expr) => {
@@ -126,7 +109,11 @@ impl FlowLogic for Shell {
                     }
                 }
 
-                handle_signal!(self.execute_statements(statements.clone()));
+                match self.execute_statements(statements) {
+                    Condition::Break => break,
+                    Condition::SigInt => return Condition::SigInt,
+                    Condition::Continue | Condition::NoOp => (),
+                }
             };
         }
 
@@ -153,19 +140,15 @@ impl FlowLogic for Shell {
         Condition::NoOp
     }
 
-    fn execute_while(
-        &mut self,
-        expression: Vec<Statement>,
-        statements: Vec<Statement>,
-    ) -> Condition {
+    fn execute_while(&mut self, expression: &[Statement], statements: &[Statement]) -> Condition {
         loop {
-            self.execute_statements(expression.clone());
+            self.execute_statements(expression);
             if self.previous_status != 0 {
                 return Condition::NoOp;
             }
 
             // Cloning is needed so the statement can be re-iterated again if needed.
-            match self.execute_statements(statements.clone()) {
+            match self.execute_statements(statements) {
                 Condition::Break => return Condition::NoOp,
                 Condition::SigInt => return Condition::SigInt,
                 _ => (),
@@ -173,10 +156,10 @@ impl FlowLogic for Shell {
         }
     }
 
-    fn execute_statement(&mut self, statement: Statement) -> Condition {
+    fn execute_statement(&mut self, statement: &Statement) -> Condition {
         match statement {
             Statement::Error(number) => {
-                self.previous_status = number;
+                self.previous_status = *number;
                 self.variables.set("?", self.previous_status.to_string());
                 self.flow_control.reset();
             }
@@ -189,26 +172,32 @@ impl FlowLogic for Shell {
                 self.variables.set("?", self.previous_status.to_string());
             }
             Statement::While { expression, statements } => {
-                if let Condition::SigInt = self.execute_while(expression, statements) {
+                if self.execute_while(&expression, &statements) == Condition::SigInt {
                     return Condition::SigInt;
                 }
             }
             Statement::For { variables, values, statements } => {
-                if let Condition::SigInt = self.execute_for(&variables, &values, statements) {
+                if self.execute_for(&variables, &values, &statements) == Condition::SigInt {
                     return Condition::SigInt;
                 }
             }
             Statement::If { expression, success, else_if, failure, .. } => {
-                match self.execute_if(expression, success, else_if, failure) {
-                    Condition::Break => return Condition::Break,
-                    Condition::Continue => return Condition::Continue,
-                    Condition::NoOp => (),
-                    Condition::SigInt => return Condition::SigInt,
+                let condition = self.execute_if(&expression, &success, &else_if, &failure);
+
+                if condition != Condition::NoOp {
+                    return condition;
                 }
             }
             Statement::Function { name, args, statements, description } => {
-                self.variables
-                    .set(&name, Function::new(description, name.clone(), args, statements));
+                self.variables.set(
+                    &name,
+                    Function::new(
+                        description.clone(),
+                        name.clone(),
+                        args.to_vec(),
+                        statements.to_vec(),
+                    ),
+                );
             }
             Statement::Pipeline(pipeline) => match expand_pipeline(&self, &pipeline) {
                 Ok((mut pipeline, statements)) => {
@@ -220,7 +209,7 @@ impl FlowLogic for Shell {
                         self.exit(status);
                     }
                     if !statements.is_empty() {
-                        self.execute_statements(statements);
+                        self.execute_statements(&statements);
                     }
                 }
                 Err(e) => {
@@ -232,63 +221,46 @@ impl FlowLogic for Shell {
                 }
             },
             Statement::Time(box_statement) => {
-                let time = ::std::time::Instant::now();
+                let time = std::time::Instant::now();
 
-                let condition = self.execute_statement(*box_statement);
+                let condition = self.execute_statement(box_statement);
 
                 let duration = time.elapsed();
                 let seconds = duration.as_secs();
                 let nanoseconds = duration.subsec_nanos();
 
-                let stdout = stdout();
-                let mut stdout = stdout.lock();
-                let _ = if seconds > 60 {
-                    writeln!(
-                        stdout,
-                        "real    {}m{:02}.{:09}s",
-                        seconds / 60,
-                        seconds % 60,
-                        nanoseconds
-                    )
+                if seconds > 60 {
+                    println!("real    {}m{:02}.{:09}s", seconds / 60, seconds % 60, nanoseconds);
                 } else {
-                    writeln!(stdout, "real    {}.{:09}s", seconds, nanoseconds)
-                };
-                match condition {
-                    Condition::Break => return Condition::Break,
-                    Condition::Continue => return Condition::Continue,
-                    Condition::NoOp => (),
-                    Condition::SigInt => return Condition::SigInt,
+                    println!("real    {}.{:09}s", seconds, nanoseconds);
+                }
+                if condition != Condition::NoOp {
+                    return condition;
                 }
             }
             Statement::And(box_statement) => {
                 let condition = match self.previous_status {
-                    SUCCESS => self.execute_statement(*box_statement),
+                    SUCCESS => self.execute_statement(box_statement),
                     _ => Condition::NoOp,
                 };
 
-                match condition {
-                    Condition::Break => return Condition::Break,
-                    Condition::Continue => return Condition::Continue,
-                    Condition::NoOp => (),
-                    Condition::SigInt => return Condition::SigInt,
+                if condition != Condition::NoOp {
+                    return condition;
                 }
             }
             Statement::Or(box_statement) => {
                 let condition = match self.previous_status {
-                    FAILURE => self.execute_statement(*box_statement),
+                    FAILURE => self.execute_statement(box_statement),
                     _ => Condition::NoOp,
                 };
 
-                match condition {
-                    Condition::Break => return Condition::Break,
-                    Condition::Continue => return Condition::Continue,
-                    Condition::NoOp => (),
-                    Condition::SigInt => return Condition::SigInt,
+                if condition != Condition::NoOp {
+                    return condition;
                 }
             }
             Statement::Not(box_statement) => {
                 // NOTE: Should the condition be used?
-                let _condition = self.execute_statement(*box_statement);
+                let _condition = self.execute_statement(box_statement);
                 match self.previous_status {
                     FAILURE => self.previous_status = SUCCESS,
                     SUCCESS => self.previous_status = FAILURE,
@@ -299,12 +271,13 @@ impl FlowLogic for Shell {
             }
             Statement::Break => return Condition::Break,
             Statement::Continue => return Condition::Continue,
-            Statement::Match { expression, cases } => match self.execute_match(expression, cases) {
-                Condition::Break => return Condition::Break,
-                Condition::Continue => return Condition::Continue,
-                Condition::NoOp => (),
-                Condition::SigInt => return Condition::SigInt,
-            },
+            Statement::Match { expression, cases } => {
+                let condition = self.execute_match(expression, &cases);
+
+                if condition != Condition::NoOp {
+                    return condition;
+                }
+            }
             _ => {}
         }
         if let Some(signal) = signals::SignalHandler.next() {
@@ -320,26 +293,21 @@ impl FlowLogic for Shell {
         }
     }
 
-    fn execute_statements(&mut self, statements: Vec<Statement>) -> Condition {
+    fn execute_statements(&mut self, statements: &[Statement]) -> Condition {
         self.variables.new_scope(false);
 
-        let mut condition = None;
-        for statement in statements {
-            match self.execute_statement(statement) {
-                Condition::NoOp => {}
-                cond => {
-                    condition = Some(cond);
-                    break;
-                }
-            }
-        }
+        let condition = statements
+            .iter()
+            .map(|statement| self.execute_statement(statement))
+            .find(|&condition| condition != Condition::NoOp)
+            .unwrap_or(Condition::NoOp);
 
         self.variables.pop_scope();
 
-        condition.unwrap_or(Condition::NoOp)
+        condition
     }
 
-    fn execute_match(&mut self, expression: small::String, cases: Vec<Case>) -> Condition {
+    fn execute_match<T: AsRef<str>>(&mut self, expression: T, cases: &[Case]) -> Condition {
         // Logic for determining if the LHS of a match-case construct (the value we are
         // matching against) matches the RHS of a match-case construct (a value
         // in a case statement). For example, checking to see if the value
@@ -347,108 +315,53 @@ impl FlowLogic for Shell {
         // ```ignore
         // matches("foo", "bar")
         // ```
-        fn matches(lhs: &types::Array, rhs: &types::Array) -> bool {
-            for v in lhs {
-                if rhs.contains(&v) {
-                    return true;
-                }
-            }
-            false
-        }
-
-        let is_array = is_array(&expression);
-        let value = expand_string(&expression, self, false);
-        let mut condition = Condition::NoOp;
-        for case in cases {
-            // let pattern_is_array = is_array(&value);
-            let pattern = case.value.map(|v| expand_string(&v, self, false));
-            match pattern {
-                None => {
-                    let mut previous_bind = None;
-                    if let Some(ref bind) = case.binding {
-                        if is_array {
-                            previous_bind =
-                                self.variables.get::<types::Array>(bind).map(Value::Array);
-                            self.variables.set(&bind, value.clone());
-                        } else {
-                            previous_bind = self.variables.get::<types::Str>(bind).map(Value::Str);
-                            self.set(&bind, value.join(" "));
-                        }
+        let is_array = is_array(expression.as_ref());
+        let value = expand_string(expression.as_ref(), self, false);
+        for case in cases.iter() {
+            if case
+                .value
+                .as_ref()
+                .map(|v| expand_string(&v, self, false))
+                .filter(|v| v.iter().all(|v| !value.contains(v)))
+                .is_none()
+            {
+                // let pattern_is_array = is_array(&value);
+                let previous_bind = case.binding.as_ref().and_then(|bind| {
+                    if is_array {
+                        let out = self.variables.get::<types::Array>(bind).map(Value::Array);
+                        self.set(&bind, value.clone());
+                        out
+                    } else {
+                        let out = self.variables.get::<types::Str>(bind).map(Value::Str);
+                        self.set(&bind, value.join(" "));
+                        out
                     }
+                });
 
-                    if let Some(statement) = case.conditional {
-                        self.on_command(&statement);
-                        if self.previous_status != SUCCESS {
-                            continue;
-                        }
+                if let Some(statement) = case.conditional.as_ref() {
+                    self.on_command(statement);
+                    if self.previous_status != SUCCESS {
+                        continue;
                     }
-
-                    condition = self.execute_statements(case.statements);
-
-                    if let Some(ref bind) = case.binding {
-                        if let Some(value) = previous_bind {
-                            match value {
-                                str_ @ Value::Str(_) => {
-                                    self.set(bind, str_);
-                                }
-                                array @ Value::Array(_) => {
-                                    self.variables.set(bind, array);
-                                }
-                                map @ Value::HashMap(_) => {
-                                    self.variables.set(bind, map);
-                                }
-                                _ => (),
-                            }
-                        }
-                    }
-
-                    break;
                 }
-                Some(ref v) if matches(v, &value) => {
-                    let mut previous_bind = None;
-                    if let Some(ref bind) = case.binding {
-                        if is_array {
-                            previous_bind =
-                                self.variables.get::<types::Array>(bind).map(Value::Array);
-                            self.variables.set(&bind, value.clone());
-                        } else {
-                            previous_bind = self.variables.get::<types::Str>(bind).map(Value::Str);
-                            self.set(&bind, value.join(" "));
-                        }
-                    }
 
-                    if let Some(statement) = case.conditional {
-                        self.on_command(&statement);
-                        if self.previous_status != SUCCESS {
-                            continue;
-                        }
-                    }
+                let condition = self.execute_statements(&case.statements);
 
-                    condition = self.execute_statements(case.statements);
-
-                    if let Some(ref bind) = case.binding {
-                        if let Some(value) = previous_bind {
-                            match value {
-                                str_ @ Value::Str(_) => {
-                                    self.set(bind, str_);
-                                }
-                                array @ Value::Array(_) => {
-                                    self.set(bind, array);
-                                }
-                                map @ Value::HashMap(_) => {
-                                    self.set(bind, map);
-                                }
-                                _ => (),
+                if let Some(ref bind) = case.binding {
+                    if let Some(value) = previous_bind {
+                        match value {
+                            Value::HashMap(_) | Value::Array(_) | Value::Str(_) => {
+                                self.set(bind, value);
                             }
+                            _ => (),
                         }
                     }
-
-                    break;
                 }
-                Some(_) => (),
+
+                return condition;
             }
         }
-        condition
+        return Condition::NoOp;
     }
 
     fn on_command(&mut self, command_string: &str) {
@@ -465,7 +378,7 @@ impl FlowLogic for Shell {
                     return;
                 }
                 Ok(Some(stm)) => {
-                    let _ = self.execute_statement(stm);
+                    let _ = self.execute_statement(&stm);
                 }
                 Ok(None) => {}
             }
@@ -480,13 +393,12 @@ fn expand_pipeline(
     shell: &Shell,
     pipeline: &Pipeline,
 ) -> Result<(Pipeline, Vec<Statement>), String> {
-    let mut item_iter = pipeline.items.iter();
-    let mut items: Vec<PipeItem> = Vec::new();
+    let mut item_iter = pipeline.items.iter().cloned();
+    let mut items: Vec<PipeItem> = Vec::with_capacity(item_iter.size_hint().0);
     let mut statements = Vec::new();
 
     while let Some(item) = item_iter.next() {
-        let possible_alias = shell.variables.get::<types::Alias>(item.job.command.as_ref());
-        if let Some(alias) = possible_alias {
+        if let Some(alias) = shell.variables.get::<types::Alias>(item.job.command.as_ref()) {
             statements = StatementSplitter::new(alias.0.as_str()).map(parse_and_validate).collect();
 
             // First item in the alias should be a pipeline item, otherwise it cannot
@@ -498,14 +410,10 @@ fn expand_pipeline(
                     first.inputs = item.inputs.clone();
 
                     // Add alias arguments to expanded args if there's any.
-                    if item.job.args.len() > 1 {
-                        for arg in &item.job.args[1..] {
-                            first.job.args.push(arg.clone());
-                        }
-                    }
+                    first.job.args.extend(item.job.args.iter().skip(1).cloned());
                 }
                 if len == 1 {
-                    if let Some(last) = pline.items.last_mut() {
+                    if let Some(mut last) = pline.items.last_mut() {
                         last.outputs = item.outputs.clone();
                         last.job.kind = item.job.kind;
                     }
@@ -516,13 +424,12 @@ fn expand_pipeline(
 
             // Handle pipeline being broken half by i.e.: '&&' or '||'
             if !statements.is_empty() {
-                let err = match statements.last_mut().unwrap() {
+                match statements.last_mut().unwrap() {
                     Statement::And(ref mut boxed_stm)
                     | Statement::Or(ref mut boxed_stm)
                     | Statement::Not(ref mut boxed_stm)
                     | Statement::Time(ref mut boxed_stm) => {
-                        let stm = &mut **boxed_stm;
-                        if let Statement::Pipeline(ref mut pline) = stm {
+                        if let Statement::Pipeline(ref mut pline) = &mut **boxed_stm {
                             // Set output of alias to be the output of last pipeline.
                             if let Some(last) = pline.items.last_mut() {
                                 last.outputs = item.outputs.clone();
@@ -530,24 +437,17 @@ fn expand_pipeline(
                             }
                             // Append rest of the pipeline to the last pipeline in the
                             // alias.
-                            for item in item_iter {
-                                pline.items.push(item.clone());
-                            }
-                            // No error
-                            false
+                            pline.items.extend(item_iter);
                         } else {
                             // Error in expansion
-                            true
+                            return Err(format!(
+                                "unable to pipe outputs of alias: '{} = {}'",
+                                item.job.command.as_str(),
+                                alias.0.as_str()
+                            ));
                         }
                     }
-                    _ => false,
-                };
-                if err {
-                    return Err(format!(
-                        "unable to pipe outputs of alias: '{} = {}'",
-                        item.job.command.as_str(),
-                        alias.0.as_str()
-                    ));
+                    _ => (),
                 }
                 break;
             }
diff --git a/src/lib/shell/flow_control.rs b/src/lib/shell/flow_control.rs
index 73aac3d102804acb97499a0b765c3be4b400e673..1fd6372d3e1c805ab0da74cff7fc8272bc9f45b8 100644
--- a/src/lib/shell/flow_control.rs
+++ b/src/lib/shell/flow_control.rs
@@ -179,177 +179,173 @@ pub(crate) fn insert_statement(
         | Statement::While { .. }
         | Statement::Match { .. }
         | Statement::If { .. }
-        | Statement::Function { .. } => flow_control.block.push(statement),
+        | Statement::Function { .. } => {
+            flow_control.block.push(statement);
+            Ok(None)
+        }
         // Case is special as it should pop back previous Case
         Statement::Case(_) => {
-            let mut top_is_case = false;
             match flow_control.block.last() {
-                Some(Statement::Case(_)) => top_is_case = true,
+                Some(Statement::Case(_)) => {
+                    let case = flow_control.block.pop().unwrap();
+                    let _ = insert_into_block(&mut flow_control.block, case);
+                }
                 Some(Statement::Match { .. }) => (),
                 _ => return Err("ion: error: Case { .. } found outside of Match { .. } block"),
             }
 
-            if top_is_case {
-                let case = flow_control.block.pop().unwrap();
-                let _ = insert_into_block(&mut flow_control.block, case);
-            }
             flow_control.block.push(statement);
+            Ok(None)
         }
         Statement::End => {
             match flow_control.block.len() {
-                0 => return Err("ion: error: keyword End found but no block to close"),
+                0 => Err("ion: error: keyword End found but no block to close"),
                 // Ready to return the complete block
-                1 => return Ok(flow_control.block.pop()),
+                1 => Ok(flow_control.block.pop()),
                 // Merge back the top block into the previous one
                 _ => {
                     let block = flow_control.block.pop().unwrap();
-                    match block {
-                        Statement::Case(_) => {
-                            // Merge last Case back and pop off Match too
-                            insert_into_block(&mut flow_control.block, block)?;
-                            let match_stm = flow_control.block.pop().unwrap();
-                            if !flow_control.block.is_empty() {
-                                insert_into_block(&mut flow_control.block, match_stm)?;
-                            } else {
-                                return Ok(Some(match_stm));
-                            }
+                    let mut case = false;
+                    if let Statement::Case(_) = block {
+                        case = true;
+                    }
+                    insert_into_block(&mut flow_control.block, block)?;
+                    if case {
+                        // Merge last Case back and pop off Match too
+                        let match_stm = flow_control.block.pop().unwrap();
+                        if !flow_control.block.is_empty() {
+                            insert_into_block(&mut flow_control.block, match_stm)?;
+
+                            Ok(None)
+                        } else {
+                            Ok(Some(match_stm))
                         }
-                        _ => insert_into_block(&mut flow_control.block, block)?,
+                    } else {
+                        Ok(None)
                     }
                 }
             }
         }
         Statement::And(_) | Statement::Or(_) if !flow_control.block.is_empty() => {
             let mut pushed = true;
-            if let Some(top) = flow_control.block.last_mut() {
-                match top {
-                    Statement::If {
-                        ref mut expression,
-                        ref mode,
-                        ref success,
-                        ref mut else_if,
-                        ..
-                    } => match *mode {
-                        0 if success.is_empty() => {
-                            // Insert into If expression if there's no previous statement.
-                            expression.push(statement.clone());
-                        }
-                        1 => {
-                            // Try to insert into last ElseIf expression if there's no previous
-                            // statement.
-                            if let Some(eif) = else_if.last_mut() {
-                                if eif.success.is_empty() {
-                                    eif.expression.push(statement.clone());
-                                } else {
-                                    pushed = false;
-                                }
+            match flow_control.block.last_mut().unwrap() {
+                Statement::If {
+                    ref mut expression,
+                    ref mode,
+                    ref success,
+                    ref mut else_if,
+                    ..
+                } => match *mode {
+                    0 if success.is_empty() => {
+                        // Insert into If expression if there's no previous statement.
+                        expression.push(statement.clone());
+                    }
+                    1 => {
+                        // Try to insert into last ElseIf expression if there's no previous
+                        // statement.
+                        if let Some(eif) = else_if.last_mut() {
+                            if eif.success.is_empty() {
+                                eif.expression.push(statement.clone());
                             } else {
-                                // should not be reached...
-                                unreachable!("Missmatch in 'If' mode!")
+                                pushed = false;
                             }
-                        }
-                        _ => pushed = false,
-                    },
-                    Statement::While { ref mut expression, ref statements } => {
-                        if statements.is_empty() {
-                            expression.push(statement.clone());
                         } else {
-                            pushed = false;
+                            // should not be reached...
+                            unreachable!("Missmatch in 'If' mode!")
                         }
                     }
                     _ => pushed = false,
+                },
+                Statement::While { ref mut expression, ref statements } => {
+                    if statements.is_empty() {
+                        expression.push(statement.clone());
+                    } else {
+                        pushed = false;
+                    }
                 }
-            } else {
-                unreachable!()
+                _ => pushed = false,
             }
             if !pushed {
                 insert_into_block(&mut flow_control.block, statement)?;
             }
+
+            Ok(None)
         }
         Statement::Time(inner) => {
             if inner.is_block() {
                 flow_control.block.push(Statement::Time(inner));
+                Ok(None)
             } else {
-                return Ok(Some(Statement::Time(inner)));
+                Ok(Some(Statement::Time(inner)))
             }
         }
         _ => {
             if !flow_control.block.is_empty() {
                 insert_into_block(&mut flow_control.block, statement)?;
+                Ok(None)
             } else {
                 // Filter out toplevel statements that should produce an error
                 // otherwise return the statement for immediat execution
                 match statement {
                     Statement::ElseIf(_) => {
-                        return Err("ion: error: found ElseIf { .. } without If { .. } block");
-                    }
-                    Statement::Else => return Err("ion: error: found Else without If { .. } block"),
-                    Statement::Break => return Err("ion: error: found Break without loop body"),
-                    Statement::Continue => {
-                        return Err("ion: error: found Continue without loop body");
+                        Err("ion: error: found ElseIf { .. } without If { .. } block")
                     }
+                    Statement::Else => Err("ion: error: found Else without If { .. } block"),
+                    Statement::Break => Err("ion: error: found Break without loop body"),
+                    Statement::Continue => Err("ion: error: found Continue without loop body"),
                     // Toplevel statement, return to execute immediately
-                    _ => return Ok(Some(statement)),
+                    _ => Ok(Some(statement)),
                 }
             }
         }
     }
-    Ok(None)
 }
 
 fn insert_into_block(block: &mut Vec<Statement>, statement: Statement) -> Result<(), &'static str> {
-    if let Some(top_block) = block.last_mut() {
-        let block = match top_block {
-            Statement::Time(inner) => inner,
-            _ => top_block,
-        };
-
-        match block {
-            Statement::Function { ref mut statements, .. } => statements.push(statement),
-            Statement::For { ref mut statements, .. } => statements.push(statement),
-            Statement::While { ref mut statements, .. } => statements.push(statement),
-            Statement::Match { ref mut cases, .. } => match statement {
-                Statement::Case(case) => cases.push(case),
-                _ => {
-                    return Err(
-                        "ion: error: statement found outside of Case { .. } block in Match { .. }"
-                    );
-                }
-            },
-            Statement::Case(ref mut case) => case.statements.push(statement),
-            Statement::If {
-                ref mut success,
-                ref mut else_if,
-                ref mut failure,
-                ref mut mode,
-                ..
-            } => match statement {
-                Statement::ElseIf(eif) => {
-                    if *mode > 1 {
-                        return Err("ion: error: ElseIf { .. } found after Else");
-                    } else {
-                        *mode = 1;
-                        else_if.push(eif);
-                    }
+    let block = match block.last_mut().expect("Should not insert statement if stack is empty!") {
+        Statement::Time(inner) => inner,
+        top_block @ _ => top_block,
+    };
+
+    match block {
+        Statement::Function { ref mut statements, .. } => statements.push(statement),
+        Statement::For { ref mut statements, .. } => statements.push(statement),
+        Statement::While { ref mut statements, .. } => statements.push(statement),
+        Statement::Match { ref mut cases, .. } => match statement {
+            Statement::Case(case) => cases.push(case),
+            _ => {
+                return Err(
+                    "ion: error: statement found outside of Case { .. } block in Match { .. }"
+                );
+            }
+        },
+        Statement::Case(ref mut case) => case.statements.push(statement),
+        Statement::If {
+            ref mut success, ref mut else_if, ref mut failure, ref mut mode, ..
+        } => match statement {
+            Statement::ElseIf(eif) => {
+                if *mode > 1 {
+                    return Err("ion: error: ElseIf { .. } found after Else");
+                } else {
+                    *mode = 1;
+                    else_if.push(eif);
                 }
-                Statement::Else => {
-                    if *mode == 2 {
-                        return Err("ion: error: Else block already exists");
-                    } else {
-                        *mode = 2;
-                    }
+            }
+            Statement::Else => {
+                if *mode == 2 {
+                    return Err("ion: error: Else block already exists");
+                } else {
+                    *mode = 2;
                 }
-                _ => match *mode {
-                    0 => success.push(statement),
-                    1 => else_if.last_mut().unwrap().success.push(statement),
-                    2 => failure.push(statement),
-                    _ => unreachable!(),
-                },
+            }
+            _ => match *mode {
+                0 => success.push(statement),
+                1 => else_if.last_mut().unwrap().success.push(statement),
+                2 => failure.push(statement),
+                _ => unreachable!(),
             },
-            _ => unreachable!("Not block-like statement pushed to stack!"),
-        }
-    } else {
-        unreachable!("Should not insert statement if stack is empty!")
+        },
+        _ => unreachable!("Not block-like statement pushed to stack!"),
     }
     Ok(())
 }
@@ -390,27 +386,25 @@ impl Function {
             return Err(FunctionError::InvalidArgumentCount);
         }
 
-        let name = self.name.clone();
-
-        let mut values: SmallVec<[_; 8]> = SmallVec::new();
-
-        for (type_, value) in self.args.iter().zip(args.iter().skip(1)) {
-            let value = match value_check(shell, value.as_ref(), &type_.kind) {
-                Ok(value) => value,
-                Err(_) => {
-                    return Err(FunctionError::InvalidArgumentType(
+        let values = self
+            .args
+            .iter()
+            .zip(args.iter().skip(1))
+            .map(|(type_, value)| {
+                if let Ok(value) = value_check(shell, value.as_ref(), &type_.kind) {
+                    Ok((type_.clone(), value))
+                } else {
+                    Err(FunctionError::InvalidArgumentType(
                         type_.kind.clone(),
                         value.as_ref().into(),
-                    ));
+                    ))
                 }
-            };
-
-            values.push((type_.clone(), value));
-        }
+            })
+            .collect::<Result<SmallVec<[_; 8]>, _>>()?;
 
         let index = shell
             .variables
-            .index_scope_for_var(&name)
+            .index_scope_for_var(&self.name)
             .expect("execute called with invalid function");
 
         // Pop off all scopes since function temporarily
@@ -422,7 +416,7 @@ impl Function {
             shell.variables.shadow(&type_.name, value);
         }
 
-        shell.execute_statements(self.statements);
+        shell.execute_statements(&self.statements);
 
         shell.variables.pop_scope();
         shell.variables.append_scopes(temporary);