diff --git a/benches/herestring.ion b/benches/herestring.ion
new file mode 100644
index 0000000000000000000000000000000000000000..381b87cfd9830c639c639b3a9bd9bb2d6ced3343
--- /dev/null
+++ b/benches/herestring.ion
@@ -0,0 +1,128 @@
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
+cat << EOF
+aueaue
+uaei
+ui
+e
+aui
+eauieaue
+au
+ei
+auieaui
+e
+aue
+aui
+eauie
+iaue
+EOF
diff --git a/benches/terminator.rs b/benches/terminator.rs
index e3b31830386b95733062cff57ade6f1d5e61fd24..5442a0e9ff571074c72e70139c3ba9c401ec2044 100644
--- a/benches/terminator.rs
+++ b/benches/terminator.rs
@@ -5,14 +5,26 @@ use criterion::Criterion;
 use ion_shell::parser::Terminator;
 
 const TEXT: &str = include_str!("test.ion");
+const EOF: &str = include_str!("herestring.ion");
 
 fn criterion_benchmark(c: &mut Criterion) {
-    c.bench_function("terminator", |b| b.iter(|| {
-        let mut bytes = TEXT.bytes().peekable();
-        while bytes.peek().is_some() {
-            println!("{:?}", Terminator::new(&mut bytes).terminate());
-        }
-    }));
+    c.bench_function("terminator", |b| {
+        b.iter(|| {
+            let mut bytes = TEXT.bytes().peekable();
+            while bytes.peek().is_some() {
+                let stmt = Terminator::new(&mut bytes).terminate();
+            }
+        })
+    });
+
+    c.bench_function("terminator EOF", |b| {
+        b.iter(|| {
+            let mut bytes = EOF.bytes().peekable();
+            while bytes.peek().is_some() {
+                let stmt = Terminator::new(&mut bytes).terminate();
+            }
+        })
+    });
 }
 
 criterion_group!(benches, criterion_benchmark);
diff --git a/benches/test.ion b/benches/test.ion
index b289864c4e2c10b7690a2cf4e1a2e4dcb38df604..e68c46e161afea24f55ee64d5fe326c1f4cefc5e 100644
--- a/benches/test.ion
+++ b/benches/test.ion
@@ -134,3 +134,277 @@ else
         >++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<-----.---.+\
         ++.---.[-]<<<]'
 end
+
+fn execute_bf program
+    let program_counter: int = 0
+
+    let memory: hmap[int] = []
+    let memory_pointer: int = 0
+
+    let stack: hmap[int] = []
+    let stack_pointer: int = 0
+
+    let jumps: hmap[int] = []
+
+    let jumps_program_counter: int = 0
+    while test $jumps_program_counter -lt $len($program)
+        if test $program[$jumps_program_counter] = "["
+            let search_depth: int = 0
+            let jump_target: int = $jumps_program_counter
+            while test $search_depth -ge 0
+                let jump_target += 1
+                test $jump_target -ge $len($program) && exit
+
+                match $program[$jump_target]
+                    case "["; let search_depth += 1
+                    case "]"; let search_depth -= 1
+                end
+            end
+            let jumps[$jumps_program_counter] = $jump_target
+        end
+        let jumps_program_counter += 1
+    end
+
+    let memory[0] = 0
+    while test $program_counter -lt $len($program)
+        match $program[$program_counter]
+            case "+"
+                if test @memory[$memory_pointer] -eq 255
+                    let memory[$memory_pointer] = 0
+                else
+                    let memory_value = @memory[$memory_pointer]
+                    let memory[$memory_pointer] = $((1 + memory_value))
+                    # TODO: let memory[$memory_pointer] += 1
+                end
+            case "-"
+                if test @memory[$memory_pointer] -eq 0
+                    let memory[$memory_pointer] = 255
+                else
+                    let memory_value = @memory[$memory_pointer]
+                    let memory[$memory_pointer] = $((-1 + memory_value))
+                    # TODO: let memory[$memory_pointer] -= 1
+                end
+            case ">"
+                let memory_pointer += 1
+                if test @memory[$memory_pointer] = ""
+                    let memory[$memory_pointer] = 0
+                end
+            case "<"
+                let memory_pointer -= 1
+                if test @memory[$memory_pointer] = ""
+                    let memory[$memory_pointer] = 0
+                end
+            case "["
+                let memory_value = @memory[$memory_pointer]
+                if test $memory_value -ne 0
+                    let stack[$stack_pointer] = $program_counter
+                    let stack_pointer += 1
+                else
+                    let program_counter = @jumps[$program_counter]
+                end
+            case "]"
+                let stack_pointer -= 1
+                let program_counter = @stack[$stack_pointer]
+                let program_counter -= 1
+            case "."
+                # TODO: Nicer decimal to ASCII conversion
+                printf \\$(printf '%03o' @memory[$memory_pointer])
+            case ","
+                echo Input not supported yet
+        end
+
+        let program_counter += 1
+    end
+end
+
+if test @args[1] != ""
+    execute_bf @args[1]
+else
+    execute_bf '-[------->+<]>.++++++.-.++[----->++<]>.>-[--->+<]>--.----------\
+        -.---.+++++++..>++++++++++.'
+
+    execute_bf '++++[++++>---<]>-.>-[--->+<]>---.--[->++++<]>+.++++++++.+++++.-\
+        -------.>-[--->+<]>.-[----->+<]>-.++++++++.---[->++++<]>.++[->++<]>.+.+\
+        +++++++.++.>++++++++++.'
+
+    # https://github.com/brain-lang/brainfuck/blob/master/examples/sierpinski.bf
+    execute_bf '[.--..]++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]\
+        +>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+][.]'
+
+    # https://www.rosettacode.org/wiki/99_Bottles_of_Beer/EsoLang
+    execute_bf '>+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>[-]\
+        <<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-]++++++\
+        +++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]>\
+        [<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+<<-]\
+        >>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++\
+        ++++>-]<++.>+++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-\
+        ]>>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>++\
+        +++++++[<+++++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++\
+        +++++++++>-]<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++\
+        [<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++++++++++>-\
+        ]<++++.------------.---.>+++++++[<---------->-]<+.>++++++++[<++++++++++\
+        +>-]<-.>++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<----\
+        -.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>++++[<++++++>-]<--\
+        .>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..--------.-------.\
+        >>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<++++\
+        ++++>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<---------->-]<\
+        .>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]\
+        <-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++.------.>++\
+        +++++[<---------->-]<+.>++++++++[<++++++++++>-]<-.-.---------.>+++++++[\
+        <---------->-]<+.>+++++++[<++++++++++>-]<--.+++++++++++.++++++++.------\
+        ---.>++++++++[<---------->-]<++.>+++++[<+++++++++++++>-]<.+++++++++++++\
+        .----------.>+++++++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<\
+        ----->-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<+++++\
+        +++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++.>+++++[<+++++++\
+        ++++++>-]<.>+++[<++++++>-]<-.---.++++++.-------.----------.>++++++++[<-\
+        ---------->-]<+.---.[-]<<<->[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<++++++\
+        +++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-\
+        ]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<\
+        <-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>\
+        >-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]\
+        <++.>+++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<\
+        <+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++\
+        [<+++++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<+++++++++\
+        ++>-]<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++[<+++++\
+        ++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++++++++++>-]<++++.\
+        ------------.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-.\
+        >++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<-----.---.+\
+        ++.---.[-]<<<]'
+end
+
+fn execute_bf program
+    let program_counter: int = 0
+
+    let memory: hmap[int] = []
+    let memory_pointer: int = 0
+
+    let stack: hmap[int] = []
+    let stack_pointer: int = 0
+
+    let jumps: hmap[int] = []
+
+    let jumps_program_counter: int = 0
+    while test $jumps_program_counter -lt $len($program)
+        if test $program[$jumps_program_counter] = "["
+            let search_depth: int = 0
+            let jump_target: int = $jumps_program_counter
+            while test $search_depth -ge 0
+                let jump_target += 1
+                test $jump_target -ge $len($program) && exit
+
+                match $program[$jump_target]
+                    case "["; let search_depth += 1
+                    case "]"; let search_depth -= 1
+                end
+            end
+            let jumps[$jumps_program_counter] = $jump_target
+        end
+        let jumps_program_counter += 1
+    end
+
+    let memory[0] = 0
+    while test $program_counter -lt $len($program)
+        match $program[$program_counter]
+            case "+"
+                if test @memory[$memory_pointer] -eq 255
+                    let memory[$memory_pointer] = 0
+                else
+                    let memory_value = @memory[$memory_pointer]
+                    let memory[$memory_pointer] = $((1 + memory_value))
+                    # TODO: let memory[$memory_pointer] += 1
+                end
+            case "-"
+                if test @memory[$memory_pointer] -eq 0
+                    let memory[$memory_pointer] = 255
+                else
+                    let memory_value = @memory[$memory_pointer]
+                    let memory[$memory_pointer] = $((-1 + memory_value))
+                    # TODO: let memory[$memory_pointer] -= 1
+                end
+            case ">"
+                let memory_pointer += 1
+                if test @memory[$memory_pointer] = ""
+                    let memory[$memory_pointer] = 0
+                end
+            case "<"
+                let memory_pointer -= 1
+                if test @memory[$memory_pointer] = ""
+                    let memory[$memory_pointer] = 0
+                end
+            case "["
+                let memory_value = @memory[$memory_pointer]
+                if test $memory_value -ne 0
+                    let stack[$stack_pointer] = $program_counter
+                    let stack_pointer += 1
+                else
+                    let program_counter = @jumps[$program_counter]
+                end
+            case "]"
+                let stack_pointer -= 1
+                let program_counter = @stack[$stack_pointer]
+                let program_counter -= 1
+            case "."
+                # TODO: Nicer decimal to ASCII conversion
+                printf \\$(printf '%03o' @memory[$memory_pointer])
+            case ","
+                echo Input not supported yet
+        end
+
+        let program_counter += 1
+    end
+end
+
+if test @args[1] != ""
+    execute_bf @args[1]
+else
+    execute_bf '-[------->+<]>.++++++.-.++[----->++<]>.>-[--->+<]>--.----------\
+        -.---.+++++++..>++++++++++.'
+
+    execute_bf '++++[++++>---<]>-.>-[--->+<]>---.--[->++++<]>+.++++++++.+++++.-\
+        -------.>-[--->+<]>.-[----->+<]>-.++++++++.---[->++++<]>.++[->++<]>.+.+\
+        +++++++.++.>++++++++++.'
+
+    # https://github.com/brain-lang/brainfuck/blob/master/examples/sierpinski.bf
+    execute_bf '[.--..]++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[-<<<[->[+[-]\
+        +>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<]>.>+[>>]>+][.]'
+
+    # https://www.rosettacode.org/wiki/99_Bottles_of_Beer/EsoLang
+    execute_bf '>+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>[-]\
+        <<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-]++++++\
+        +++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]>\
+        [<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+<<-]\
+        >>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++\
+        ++++>-]<++.>+++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-\
+        ]>>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>++\
+        +++++++[<+++++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++\
+        +++++++++>-]<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++\
+        [<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++++++++++>-\
+        ]<++++.------------.---.>+++++++[<---------->-]<+.>++++++++[<++++++++++\
+        +>-]<-.>++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<----\
+        -.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>++++[<++++++>-]<--\
+        .>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..--------.-------.\
+        >>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<++++\
+        ++++>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<---------->-]<\
+        .>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]\
+        <-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++.------.>++\
+        +++++[<---------->-]<+.>++++++++[<++++++++++>-]<-.-.---------.>+++++++[\
+        <---------->-]<+.>+++++++[<++++++++++>-]<--.+++++++++++.++++++++.------\
+        ---.>++++++++[<---------->-]<++.>+++++[<+++++++++++++>-]<.+++++++++++++\
+        .----------.>+++++++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<\
+        ----->-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<+++++\
+        +++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++.>+++++[<+++++++\
+        ++++++>-]<.>+++[<++++++>-]<-.---.++++++.-------.----------.>++++++++[<-\
+        ---------->-]<+.---.[-]<<<->[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<++++++\
+        +++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-\
+        ]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<\
+        <-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>\
+        >-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]\
+        <++.>+++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<\
+        <+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++\
+        [<+++++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<+++++++++\
+        ++>-]<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++[<+++++\
+        ++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++++++++++>-]<++++.\
+        ------------.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-.\
+        >++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<-----.---.+\
+        ++.---.[-]<<<]'
+end
diff --git a/src/lib/parser/quotes.rs b/src/lib/parser/quotes.rs
index b8e1144a0363785a6ca5d393754465c9bc676b16..e85c0625cfc0229064b1fdb9e37b45a33e5f74b2 100644
--- a/src/lib/parser/quotes.rs
+++ b/src/lib/parser/quotes.rs
@@ -25,7 +25,7 @@ impl EofMatcher {
             self.match_idx = 0;
         } else if c == b'\n' {
             self.complete = true;
-        } else {
+        } else if !self.eof.is_empty() || !(c as char).is_whitespace() {
             self.eof.push(c);
         }
         self.complete && self.match_idx == self.eof.len()
@@ -43,7 +43,6 @@ pub struct Terminator<I: Iterator<Item = u8>> {
     inner:      RearPeekable<I>,
     eof:        Option<EofMatcher>,
     array:      usize,
-    read:       usize,
     skip_next:  bool,
     quotes:     Quotes,
     terminated: bool,
@@ -103,10 +102,6 @@ impl<I: Iterator<Item = u8>> Iterator for Terminator<I> {
         let next = self.inner.next();
         let out = self.handle_char(next);
 
-        /*println!(
-            "debug: \n\tarray: {}\n\tquotes: {:?}\n\tcharacter: {:?}\n\ttrim: {}\n\twhitespace: {}",
-            self.array, self.quotes, out, self.skip_next, self.whitespace,
-        );*/
         if out.is_none()
             && self.eof.is_none()
             && self.array == 0
@@ -123,92 +118,97 @@ impl<I: Iterator<Item = u8>> Iterator for Terminator<I> {
 impl<I: Iterator<Item = u8>> Terminator<I> {
     /// Consumes lines until a statement is formed or the iterator runs dry, and returns the
     /// underlying `String`.
-    pub fn terminate(self) -> Result<String, ()> {
+    pub fn terminate(&mut self) -> Result<String, ()> {
         let stmt = self.collect::<Vec<_>>();
         let stmt = unsafe { String::from_utf8_unchecked(stmt) };
-        // println!("statement {:?}", stmt);
-        Ok(stmt)
+
+        if self.terminated && !stmt.is_empty() {
+            Ok(stmt)
+        } else {
+            Err(())
+        }
     }
 
     fn handle_char(&mut self, character: Option<u8>) -> Option<u8> {
         character
             .and_then(|character| {
-            let prev_whitespace = self.whitespace;
-            self.whitespace = false;
+                let prev_whitespace = self.whitespace;
+                self.whitespace = false;
 
-            if let Some(matcher) = self.eof.as_mut() {
-                if matcher.next(character) {
-                    self.eof = None;
-                }
-            } else if self.skip_next {
-                self.skip_next = false;
-            } else if self.quotes != Quotes::None && character != b'\\' {
-                match (character, &self.quotes) {
-                    (b'\'', Quotes::Single) | (b'"', Quotes::Double) => {
-                        self.quotes = Quotes::None;
-                    }
-                    _ => (),
-                }
-            } else {
-                match character {
-                    b'\'' => {
-                        self.quotes = Quotes::Single;
-                    }
-                    b'"' => {
-                        self.quotes = Quotes::Double;
+                if let Some(matcher) = self.eof.as_mut() {
+                    if matcher.next(character) {
+                        self.eof = None;
                     }
-                    b'<' if self.inner.prev() == Some(&b'<') => {
-                        if let Some(&b'<') = self.inner.peek() {
-                            self.skip_next = true; // avoid falling in the else at the next pass
-                        } else {
-                            self.eof = Some(EofMatcher::new());
+                } else if self.skip_next {
+                    self.skip_next = false;
+                } else if self.quotes != Quotes::None && character != b'\\' {
+                    match (character, &self.quotes) {
+                        (b'\'', Quotes::Single) | (b'"', Quotes::Double) => {
+                            self.quotes = Quotes::None;
                         }
+                        _ => (),
                     }
-                    b'[' => {
-                        self.array += 1;
-                    }
-                    b']' => {
-                        if self.array > 0 {
-                            self.array -= 1;
+                } else {
+                    match character {
+                        b'\'' => {
+                            self.quotes = Quotes::Single;
                         }
-                    }
-                    b'#' if self
-                        .inner
-                        .prev()
-                        .filter(|&c| ![b' ', b'\n'].contains(c))
-                        .is_none() =>
-                    {
-                        return self.inner.find(|&c| c == b'\n')
-                    }
-                    b'\\' => {
-                        if self.inner.peek() == Some(&b'\n') {
-                            let next = self.inner.find(|&c| !(c as char).is_whitespace());
-                            return self.handle_char(next);
-                        } else {
-                            self.skip_next = true;
+                        b'"' => {
+                            self.quotes = Quotes::Double;
                         }
-                    }
-                    b'&' | b'|' if self.inner.prev() == Some(&character) => {
-                        self.and_or = true;
-                    }
-                    b'\n' if self.array == 0 && !self.and_or => {
-                        self.terminated = true;
-                    }
-                    _ if (character as char).is_whitespace() => {
-                        if prev_whitespace {
-                            let next = self.inner.find(|&c| !(c as char).is_whitespace());
-                            return self.handle_char(next);
+                        b'<' if self.inner.prev() == Some(&b'<') => {
+                            if let Some(&b'<') = self.inner.peek() {
+                                self.skip_next = true; // avoid falling in the else at the next pass
+                            } else {
+                                self.eof = Some(EofMatcher::new());
+                            }
+                        }
+                        b'[' => {
+                            self.array += 1;
+                        }
+                        b']' => {
+                            if self.array > 0 {
+                                self.array -= 1;
+                            }
+                        }
+                        b'#' if self
+                            .inner
+                            .prev()
+                            .filter(|&c| ![b' ', b'\n'].contains(c))
+                            .is_none() =>
+                        {
+                            return self.inner.find(|&c| c == b'\n')
+                        }
+                        b'\\' => {
+                            if self.inner.peek() == Some(&b'\n') {
+                                let next = self.inner.find(|&c| !(c as char).is_whitespace());
+                                return self.handle_char(next);
+                            } else {
+                                self.skip_next = true;
+                            }
+                        }
+                        b'&' | b'|' if self.inner.prev() == Some(&character) => {
+                            self.and_or = true;
+                        }
+                        b'\n' if self.array == 0 && !self.and_or => {
+                            self.terminated = true;
+                        }
+                        _ if (character as char).is_whitespace() => {
+                            if prev_whitespace {
+                                let next = self.inner.find(|&c| !(c as char).is_whitespace());
+                                return self.handle_char(next);
+                            }
+                            self.whitespace = true;
+                        }
+                        _ => {
+                            self.and_or = false;
                         }
-                        self.whitespace = true;
-                    }
-                    _ => {
-                        self.and_or = false;
                     }
                 }
-            }
 
-            Some(character)
-        }).map(|c| if c == b'\n' && self.array > 0 { b' ' } else { c })
+                Some(character)
+            })
+            .map(|c| if c == b'\n' && self.array > 0 { b' ' } else { c })
     }
 
     pub fn new(inner: I) -> Terminator<I> {
@@ -216,7 +216,6 @@ impl<I: Iterator<Item = u8>> Terminator<I> {
             inner:      RearPeekable { iter: inner.peekable(), now: None, last: None },
             eof:        None,
             array:      0,
-            read:       0,
             skip_next:  false,
             quotes:     Quotes::None,
             terminated: false,
diff --git a/src/lib/shell/binary/mod.rs b/src/lib/shell/binary/mod.rs
index cbbf5d136fc1472472d94b06192f5a5ab26f0e6a..67dec0f93c1b16db456b4a6ceba3ee88c8d80391 100644
--- a/src/lib/shell/binary/mod.rs
+++ b/src/lib/shell/binary/mod.rs
@@ -98,7 +98,7 @@ impl Binary for Shell {
             })
             .filter_map(|cmd| cmd)
             .flat_map(|s| s.into_bytes().into_iter().chain(Some(b'\n')));
-            match Terminator::new(&mut lines).terminate().map(|stmt| stmt.to_string()).ok() {
+            match Terminator::new(&mut lines).terminate().ok() {
                 Some(command) => {
                     self.flags &= !UNTERMINATED;
                     let cmd: &str = &designators::expand_designators(&self, command.trim_end());
diff --git a/src/lib/shell/mod.rs b/src/lib/shell/mod.rs
index 463af44b15b446232ff902a72dbb9c0d340884c3..91c0b732054b610aba077d77c5af43c7cce386b9 100644
--- a/src/lib/shell/mod.rs
+++ b/src/lib/shell/mod.rs
@@ -234,7 +234,7 @@ impl Shell {
     where
         T: 'a + AsRef<str> + std::clone::Clone + std::convert::From<&'a str>,
     {
-        let terminator: Terminator<_> = command.as_ref().into();
+        let mut terminator: Terminator<_> = command.as_ref().into();
         if let Ok(stmt) = terminator.terminate() {
             self.on_command(&stmt);
             Ok(self.previous_status)