diff --git a/src/_REDOX b/src/_REDOX
new file mode 100644
index 0000000000000000000000000000000000000000..172bb432538c631ec58d2ab97c1648fe4962e7bd
--- /dev/null
+++ b/src/_REDOX
@@ -0,0 +1,4 @@
+name=Shell
+icon=file:/ui/mimetypes/application-x-executable-script.bmp
+author=Jeremy Soller
+description=Shell for Redox
diff --git a/src/bin/ion.rs b/src/bin/ion.rs
deleted file mode 100644
index d3d722c1e8442b2a51201f0ca7001769fa93173d..0000000000000000000000000000000000000000
--- a/src/bin/ion.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-extern crate ion;
-
-fn main() {
-    loop {
-        ion::repl()
-    }
-}
diff --git a/src/command.rs b/src/command.rs
deleted file mode 100644
index 43537b69b9fca5cc15bf23a3f8f9a94e4847dfa4..0000000000000000000000000000000000000000
--- a/src/command.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-use std::process::{Command,Output};
-
-pub struct InstructionOut {
-    pub stdout: String,
-    pub stderr: String,
-}
-
-pub fn run(args: &[&str]) -> Option<InstructionOut> {
-    let output: Option<Output>;
-    match args.len() {
-        0 => output = Command::new("").output().ok(),
-        1 => output = Command::new(&args[0]).output().ok(),
-        _ => output = Command::new(&args[0]).args(&args[1..]).output().ok(),
-    }
-    if output.is_some() {
-        let output = output.unwrap();
-        Some(InstructionOut {
-            stdout: String::from_utf8(output.stdout).ok().expect("No stdout"),
-            stderr: String::from_utf8(output.stderr).ok().expect("No stderr"),
-        })
-    } else {
-        None
-    }
-}
diff --git a/src/lib.rs b/src/lib.rs
deleted file mode 100644
index 30f9475bf1f795f02d5f81e9f4b9b73c4b87d5f6..0000000000000000000000000000000000000000
--- a/src/lib.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-#![feature(convert)]
-pub mod command;
-
-use std::io;
-use command::*;
-
-pub fn repl() {
-    let mut input = String::new();
-    match io::stdin().read_line(&mut input) {
-        Ok(_) => {
-            let out_wrap = run(input.trim().split_whitespace().collect::<Vec<&str>>().as_slice());
-            if out_wrap.is_some() {
-                let out = out_wrap.unwrap();
-                if out.stdout.is_empty() {
-                    println!("{}",out.stderr.trim());
-                } else {
-                    println!("{}",out.stdout.trim());
-                }
-            } else {
-                println!("{} is not a valid command", input.trim());
-            }
-        }
-        Err(error) => println!("Line Read Error: {}", error)
-    };
-}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0ee292adc1e027bcc863b91bf7c96dd84431dd1e
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,673 @@
+use std::collections::BTreeMap;
+use std::string::String;
+use std::vec::Vec;
+use std::boxed::Box;
+use std::fs::{self, File};
+use std::io::{stdout, stdin, Read, Write};
+use std::env;
+use std::process;
+use std::thread;
+
+use self::to_num::ToNum;
+
+pub mod to_num;
+
+macro_rules! readln {
+    () => ({
+        let mut buffer = String::new();
+        match stdin().read_line(&mut buffer) {
+            Ok(_) => Some(buffer),
+            Err(_) => None
+        }
+    });
+}
+
+/// Structure which represents a Terminal's command.
+/// This command structure contains a name, and the code which run the functionnality associated to this one, with zero, one or several argument(s).
+/// # Example
+/// ```
+/// let my_command = Command {
+///     name: "my_command",
+///     help: "Describe what my_command does followed by a newline showing usage",
+///     main: box|args: &Vec<String>| {
+///         println!("Say 'hello' to my command! :-D");
+///     }
+/// }
+/// ```
+pub struct Command {
+    pub name: &'static str,
+    pub help: &'static str,
+    pub main: Box<Fn(&Vec<String>, &mut Vec<Variable>, &mut Vec<Mode>)>,
+}
+
+impl Command {
+    /// Return the vector of the commands
+    // TODO: Use a more efficient collection instead
+    pub fn vec() -> Vec<Self> {
+        let mut commands: Vec<Self> = Vec::new();
+
+        commands.push(Command {
+            name: "cat",
+            help: "To display a file in the output\n    cat <your_file>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                let path = args.get(1).map_or(String::new(), |arg| arg.clone());
+
+                match File::open(&path) {
+                    Ok(mut file) => {
+                        let mut string = String::new();
+                        match file.read_to_string(&mut string) {
+                            Ok(_) => println!("{}", string),
+                            Err(err) => println!("Failed to read: {}: {}", path, err),
+                        }
+                    },
+                    Err(err) => println!("Failed to open file: {}: {}", path, err)
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "cd",
+            help: "To change the current directory\n    cd <your_destination>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match args.get(1) {
+                    Some(path) => {
+                        if let Err(err) = env::set_current_dir(&path) {
+                            println!("Failed to set current dir to {}: {}", path, err);
+                        }
+                    }
+                    None => println!("No path given"),
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "echo",
+            help: "To display some text in the output\n    echo Hello world!",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                let echo = args.iter()
+                               .skip(1)
+                               .fold(String::new(), |string, arg| string + " " + arg);
+                println!("{}", echo.trim());
+            }),
+        });
+
+        commands.push(Command {
+            name: "else",
+            help: "",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {}),
+        });
+
+        commands.push(Command {
+            name: "exec",
+            help: "To execute a binary in the output\n    exec <my_binary>",
+            main: Box::new(|args: &Vec<String>, variables: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                if let Some(path) = args.get(1) {
+                    let mut command = process::Command::new(path);
+                    for i in 2 .. args.len() {
+                        if let Some(arg) = args.get(i){
+                            command.arg(arg);
+                        }
+                    }
+
+                    match command.spawn() {
+                        Ok(mut child) => {
+                            match child.wait() {
+                                Ok(status) => {
+                                    if let Some(code) = status.code() {
+                                        set_var(variables, "?", &format!("{}", code));
+                                    } else {
+                                        println!("{}: No child exit code", path);
+                                    }
+                                },
+                                Err(err) => println!("{}: Failed to wait: {}", path, err)
+                            }
+                        },
+                        Err(err) => println!("{}: Failed to execute: {}", path, err)
+                    }
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "exit",
+            help: "To exit the curent session",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {}),
+        });
+
+        commands.push(Command {
+            name: "fi",
+            help: "",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {}),
+        });
+
+        commands.push(Command {
+            name: "free",
+            help: "Show memory information\n    free",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match File::open("memory:") {
+                    Ok(mut file) => {
+                        let mut string = String::new();
+                        match file.read_to_string(&mut string) {
+                            Ok(_) => println!("{}", string),
+                            Err(err) => println!("Failed to read: memory: {}", err),
+                        }
+                    }
+                    Err(err) => println!("Failed to open file: memory: {}", err)
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "if",
+            help: "",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {}),
+        });
+
+        commands.push(Command {
+            name: "ls",
+            help: "To list the content of the current directory\n    ls",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                let path = args.get(1).map_or(".".to_string(), |arg| arg.clone());
+
+                match fs::read_dir(&path) {
+                    Ok(dir) => {
+                        for entry_result in dir {
+                            match entry_result {
+                                Ok(entry) => {
+                                    match entry.path().to_str() {
+                                        Some(path_str) => println!("{}", path_str),
+                                        None => println!("?")
+                                    }
+                                },
+                                Err(err) => println!("Failed to read entry: {}", err)
+                            }
+                        }
+                    },
+                    Err(err) => println!("Failed to open directory: {}: {}", path, err)
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "mkdir",
+            help: "To create a directory in the current directory\n    mkdir <my_new_directory>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match args.get(1) {
+                    Some(dir_name) => if let Err(err) = fs::create_dir(dir_name) {
+                        println!("Failed to create: {}: {}", dir_name, err);
+                    },
+                    None => println!("No name provided"),
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "ps",
+            help: "Show process list\n    ps",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match File::open("context:") {
+                    Ok(mut file) => {
+                        let mut string = String::new();
+                        match file.read_to_string(&mut string) {
+                            Ok(_) => println!("{}", string),
+                            Err(err) => println!("Failed to read: context: {}", err),
+                        }
+                    }
+                    Err(err) => println!("Failed to open file: context: {}", err)
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "pwd",
+            help: "To output the path of the current directory\n    pwd",
+            main: Box::new(|_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match env::current_dir() {
+                    Ok(path) => match path.to_str() {
+                        Some(path_str) => println!("{}", path_str),
+                        None => println!("?")
+                    },
+                    Err(err) => println!("Failed to get current dir: {}", err)
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "read",
+            help: "To read some variables\n    read <my_variable>",
+            main: Box::new(|args: &Vec<String>, variables: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                for i in 1..args.len() {
+                    if let Some(arg_original) = args.get(i) {
+                        let arg = arg_original.trim();
+                        print!("{}=", arg);
+                        stdout().flush();
+                        if let Some(value_original) = readln!() {
+                            let value = value_original.trim();
+                            set_var(variables, arg, value);
+                        }
+                    }
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "rm",
+            help: "To remove a file, in the current directory\n    rm <my_file>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match args.get(1) {
+                    Some(file_name) => if fs::remove_file(file_name).is_err() {
+                        println!("Failed to remove: {}", file_name);
+                    },
+                    None => println!("No name provided"),
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "run",
+            help: "Run a script\n    run <script>",
+            main: Box::new(|args: &Vec<String>, variables: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                let path = "/apps/shell/main.bin";
+
+                let mut command = process::Command::new(path);
+                for i in 1 .. args.len() {
+                    if let Some(arg) = args.get(i){
+                        command.arg(arg);
+                    }
+                }
+
+                match command.spawn() {
+                    Ok(mut child) => {
+                        match child.wait() {
+                            Ok(status) => {
+                                if let Some(code) = status.code() {
+                                    set_var(variables, "?", &format!("{}", code));
+                                } else {
+                                    println!("{}: No child exit code", path);
+                                }
+                            },
+                            Err(err) => println!("{}: Failed to wait: {}", path, err)
+                        }
+                    },
+                    Err(err) => println!("{}: Failed to execute: {}", path, err)
+                }
+            })
+        });
+
+        commands.push(Command {
+            name: "sleep",
+            help: "Make a sleep in the current session\n    sleep <number_of_seconds>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                let secs = args.get(1).map_or(0, |arg| arg.to_num());
+                thread::sleep_ms(secs as u32 * 1000);
+            }),
+        });
+
+        commands.push(Command {
+            name: "send",
+            help: "To send data, via an URL\n    send <url> <data>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                if args.len() < 3 {
+                    println!("Error: incorrect arguments");
+                    println!("Usage: send <url> <data>");
+                    return;
+                }
+
+                let path = args.get(1).map_or(String::new(), |arg| arg.clone());
+
+                match File::open(&path) {
+                    Ok(mut file) => {
+                        let string: String = args.iter()
+                                                 .skip(2)
+                                                 .fold(String::new(), |s, arg| s + " " + arg) +
+                                             "\r\n\r\n";
+
+                        match file.write(string.trim_left().as_bytes()) {
+                            Ok(size) => println!("Wrote {} bytes", size),
+                            Err(err) => println!("Failed to write: {}", err),
+                        }
+
+                        let mut string = String::new();
+                        match file.read_to_string(&mut string) {
+                            Ok(_) => println!("{}", string),
+                            Err(err) => println!("Failed to read: {}", err),
+                        }
+                    },
+                    Err(err) => println!("Failed to open: {}", err)
+                }
+            }),
+        });
+
+        // Simple command to create a file, in the current directory
+        // The file has got the name given as the first argument of the command
+        // If the command have no arguments, the command don't create the file
+        commands.push(Command {
+            name: "touch",
+            help: "To create a file, in the current directory\n    touch <my_file>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                match args.get(1) {
+                    Some(file_name) => if let Err(err) = File::create(file_name) {
+                        println!("Failed to create: {}: {}", file_name, err);
+                    },
+                    None => println!("No name provided"),
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "url_hex",
+            help: "",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                let path = args.get(1).map_or(String::new(), |arg| arg.clone());
+
+                match File::open(&path) {
+                    Ok(mut file) => {
+                        let mut vec: Vec<u8> = vec![];
+                        match file.read_to_end(&mut vec) {
+                            Ok(_) => {
+                                let mut line = "HEX:".to_string();
+                                for byte in vec.iter() {
+                                    line = line + " " + &format!("{:X}", *byte);
+                                }
+                                println!("{}", line);
+                            }
+                            Err(err) => println!("Failed to read: {}", err)
+                        }
+                    }
+                    Err(err) => println!("Failed to open: {}", err)
+                }
+            }),
+        });
+
+        commands.push(Command {
+            name: "wget",
+            help: "To make some requests at a given host, using TCP protocol\n    wget <host> \
+                   <request>",
+            main: Box::new(|args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                if let Some(host) = args.get(1) {
+                    if let Some(req) = args.get(2) {
+                        if let Ok(mut con) = File::open(&("tcp://".to_string() + host)) {
+                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());
+
+                            let mut res = vec![];
+                            con.read_to_end(&mut res);
+
+                            if let Ok(mut file) = File::open(&req) {
+                                file.write(&res);
+                            }
+                        }
+                    } else {
+                        println!("No request given");
+                    }
+                } else {
+                    println!("No url given");
+                }
+            }),
+        });
+
+        // TODO: Someone should implement FromIterator for HashMap before
+        //       changing the type back to HashMap
+        let command_helper: BTreeMap<String, String> = commands
+            .iter()
+            .map(|c| (c.name.to_string(), c.help.to_string()))
+            .collect();
+
+        commands.push(Command {
+            name: "man",
+            help: "Display a little helper for a given command\n    man ls",
+            main: Box::new(move |args: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                if let Some(command) = args.get(1) {
+                    if command_helper.contains_key(command) {
+                        match command_helper.get(command) {
+                            Some(help) => println!("{}", help),
+                            None => println!("Command helper not found [run 'help']..."),
+                        }
+                    } else {
+                        println!("Command helper not found [run 'help']...");
+                    }
+                } else {
+                    println!("Please to specify a command!");
+                }
+            }),
+        });
+
+        let command_list = commands.iter().fold(String::new(), |l, c| l + " " + c.name);
+
+        commands.push(Command {
+            name: "help",
+            help: "Print available commands",
+            main: Box::new(move |_: &Vec<String>, _: &mut Vec<Variable>, _: &mut Vec<Mode>| {
+                println!("Commands:{}", command_list);
+            }),
+        });
+
+        commands
+    }
+}
+
+/// A (env) variable
+pub struct Variable {
+    pub name: String,
+    pub value: String,
+}
+
+pub struct Mode {
+    value: bool,
+}
+
+fn on_command(command_string: &str,
+              commands: &Vec<Command>,
+              variables: &mut Vec<Variable>,
+              modes: &mut Vec<Mode>) {
+    // Comment
+    if command_string.starts_with('#') {
+        return;
+    }
+
+    // Show variables
+    if command_string == "$" {
+        for variable in variables.iter() {
+            println!("{}={}", variable.name, variable.value);
+        }
+        return;
+    }
+
+    // Explode into arguments, replace variables
+    let mut args: Vec<String> = vec![];
+    for arg in command_string.split(' ') {
+        if !arg.is_empty() {
+            if arg.starts_with('$') {
+                let name = arg[1..arg.len()].to_string();
+                for variable in variables.iter() {
+                    if variable.name == name {
+                        args.push(variable.value.clone());
+                        break;
+                    }
+                }
+            } else {
+                args.push(arg.to_string());
+            }
+        }
+    }
+
+    // Execute commands
+    if let Some(cmd) = args.get(0) {
+        if cmd == "if" {
+            let mut value = false;
+
+            if let Some(left) = args.get(1) {
+                if let Some(cmp) = args.get(2) {
+                    if let Some(right) = args.get(3) {
+                        if cmp == "==" {
+                            value = *left == *right;
+                        } else if cmp == "!=" {
+                            value = *left != *right;
+                        } else if cmp == ">" {
+                            value = left.to_num_signed() > right.to_num_signed();
+                        } else if cmp == ">=" {
+                            value = left.to_num_signed() >= right.to_num_signed();
+                        } else if cmp == "<" {
+                            value = left.to_num_signed() < right.to_num_signed();
+                        } else if cmp == "<=" {
+                            value = left.to_num_signed() <= right.to_num_signed();
+                        } else {
+                            println!("Unknown comparison: {}", cmp);
+                        }
+                    } else {
+                        println!("No right hand side");
+                    }
+                } else {
+                    println!("No comparison operator");
+                }
+            } else {
+                println!("No left hand side");
+            }
+
+            modes.insert(0, Mode { value: value });
+            return;
+        }
+
+        if cmd == "else" {
+            let mut syntax_error = false;
+            match modes.get_mut(0) {
+                Some(mode) => mode.value = !mode.value,
+                None => syntax_error = true,
+            }
+            if syntax_error {
+                println!("Syntax error: else found with no previous if");
+            }
+            return;
+        }
+
+        if cmd == "fi" {
+            let mut syntax_error = false;
+            if !modes.is_empty() {
+                modes.remove(0);
+            } else {
+                syntax_error = true;
+            }
+            if syntax_error {
+                println!("Syntax error: fi found with no previous if");
+            }
+            return;
+        }
+
+        for mode in modes.iter() {
+            if !mode.value {
+                return;
+            }
+        }
+
+        // Set variables
+        if let Some(i) = cmd.find('=') {
+            let name = cmd[0..i].trim();
+            let mut value = cmd[i + 1..cmd.len()].trim().to_string();
+
+            for i in 1..args.len() {
+                if let Some(arg) = args.get(i) {
+                    value = value + " " + &arg;
+                }
+            }
+
+            set_var(variables, name, &value);
+            return;
+        }
+
+        // Commands
+        for command in commands.iter() {
+            if &command.name == cmd {
+                (*command.main)(&args, variables, modes);
+                return;
+            }
+        }
+
+        println!("Unknown command: '{}'", cmd);
+    }
+}
+
+
+pub fn set_var(variables: &mut Vec<Variable>, name: &str, value: &str) {
+    if name.is_empty() {
+        return;
+    }
+
+    if value.is_empty() {
+        let mut remove = -1;
+        for i in 0..variables.len() {
+            match variables.get(i) {
+                Some(variable) => if variable.name == name {
+                    remove = i as isize;
+                    break;
+                },
+                None => break,
+            }
+        }
+
+        if remove >= 0 {
+            variables.remove(remove as usize);
+        }
+    } else {
+        for variable in variables.iter_mut() {
+            if variable.name == name {
+                variable.value = value.to_string();
+                return;
+            }
+        }
+
+        variables.push(Variable {
+            name: name.to_string(),
+            value: value.to_string(),
+        });
+    }
+}
+
+#[no_mangle] pub fn main() {
+    let commands = Command::vec();
+    let mut variables: Vec<Variable> = vec![];
+    let mut modes: Vec<Mode> = vec![];
+
+    for arg in env::args().skip(1) {
+        let mut command_list = String::new();
+        if let Ok(mut file) = File::open(arg) {
+            file.read_to_string(&mut command_list);
+        }
+
+        for command in command_list.split('\n') {
+            on_command(&command, &commands, &mut variables, &mut modes);
+        }
+
+        return;
+    }
+
+    loop {
+        for mode in modes.iter().rev() {
+            if mode.value {
+                print!("+ ");
+            } else {
+                print!("- ");
+            }
+        }
+
+        let cwd = match env::current_dir() {
+            Ok(path) => match path.to_str() {
+                Some(path_str) => path_str.to_string(),
+                None => "?".to_string()
+            },
+            Err(_) => "?".to_string()
+        };
+
+        print!("user@redox:{}# ", cwd);
+        stdout().flush();
+
+        if let Some(command_original) = readln!() {
+            let command = command_original.trim();
+            if command == "exit" {
+                break;
+            } else if !command.is_empty() {
+                on_command(&command, &commands, &mut variables, &mut modes);
+            }
+        } else {
+            break;
+        }
+    }
+}
diff --git a/src/to_num.rs b/src/to_num.rs
new file mode 100644
index 0000000000000000000000000000000000000000..98ef92502e0fc8fc900dcbe3c4c9a48d25ede9b1
--- /dev/null
+++ b/src/to_num.rs
@@ -0,0 +1,59 @@
+//! Types convertable to integers
+
+/// Parse the string to a integer using a given radix
+pub trait ToNum {
+    fn to_num_radix(&self, radix: usize) -> usize;
+    fn to_num_radix_signed(&self, radix: usize) -> isize;
+    fn to_num(&self) -> usize;
+    fn to_num_signed(&self) -> isize;
+}
+
+impl ToNum for str {
+    fn to_num_radix(&self, radix: usize) -> usize {
+        if radix == 0 {
+            return 0;
+        }
+
+        let mut num = 0;
+        for c in self.chars() {
+            let digit;
+            if c >= '0' && c <= '9' {
+                digit = c as usize - '0' as usize
+            } else if c >= 'A' && c <= 'Z' {
+                digit = c as usize - 'A' as usize + 10
+            } else if c >= 'a' && c <= 'z' {
+                digit = c as usize - 'a' as usize + 10
+            } else {
+                break;
+            }
+
+            if digit >= radix {
+                break;
+            }
+
+            num *= radix;
+            num += digit;
+        }
+
+        num
+    }
+
+    /// Parse the string as a signed integer using a given radix
+    fn to_num_radix_signed(&self, radix: usize) -> isize {
+        if self.starts_with('-') {
+            -(self[1 ..].to_num_radix(radix) as isize)
+        } else {
+            self.to_num_radix(radix) as isize
+        }
+    }
+
+    /// Parse it as a unsigned integer in base 10
+    fn to_num(&self) -> usize {
+        self.to_num_radix(10)
+    }
+
+    /// Parse it as a signed integer in base 10
+    fn to_num_signed(&self) -> isize {
+        self.to_num_radix_signed(10)
+    }
+}