diff --git a/Cargo.toml b/Cargo.toml
index 853435157c4cfeecef5ab56072b9c5f8bc2510cc..09ee5d605990c18b930a361eb75074f3bdd2c098 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,10 @@ authors = ["Jeremy Soller <jackpot51@gmail.com>"]
 name = "redoxfs"
 path = "src/lib.rs"
 
+[[bin]]
+name = "redoxfs"
+path = "scheme/main.rs"
+
 [[bin]]
 name = "redoxfs-fuse"
 path = "fuse/main.rs"
@@ -20,6 +24,9 @@ name = "redoxfs-utility"
 path = "utility/main.rs"
 
 [dependencies]
-redox-system = {path = "../system/"}
+spin = "*"
+syscall = {path = "../../syscall/"}
+
+[target.'cfg(unix)'.dependencies]
 fuse = "0.2"
 time = "*"
diff --git a/scheme/cache/mod.rs b/scheme/cache/mod.rs
index 0798592a064d12293904feb8fb74edf6a663aca0..3df653b21db2afd1ba96c2deacc9921c5bf6d8a7 100644
--- a/scheme/cache/mod.rs
+++ b/scheme/cache/mod.rs
@@ -2,7 +2,7 @@ use std::{cmp, ptr};
 
 use redoxfs::Disk;
 
-use system::error::Result;
+use syscall::error::Result;
 
 use self::lru_cache::LruCache;
 
diff --git a/scheme/image.rs b/scheme/image.rs
index 169727095b20294fe1478512b14c5e10ab1854a8..b589c5cb69ff142a24fa96b5bb93ac4603d8fc1d 100644
--- a/scheme/image.rs
+++ b/scheme/image.rs
@@ -3,7 +3,7 @@ use std::io::{Read, Write, Seek, SeekFrom};
 
 use redoxfs::Disk;
 
-use system::error::{Error, Result, EIO};
+use syscall::error::{Error, Result, EIO};
 
 macro_rules! try_disk {
     ($expr:expr) => (match $expr {
diff --git a/scheme/main.rs b/scheme/main.rs
index e82005a9a955337db434f4f1932fd58b984205e0..d739091a6441c2ef982fa031fcefc3856b854dc1 100644
--- a/scheme/main.rs
+++ b/scheme/main.rs
@@ -1,16 +1,16 @@
 #![deny(warnings)]
 
 extern crate redoxfs;
-
-extern crate system;
+extern crate spin;
+extern crate syscall;
 
 use std::env;
 use std::fs::File;
 use std::io::{Read, Write};
 use std::mem::size_of;
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
 use std::thread;
-use std::time::Duration;
+use spin::Mutex;
 
 use cache::Cache;
 use image::Image;
@@ -18,7 +18,7 @@ use scheme::FileScheme;
 
 use redoxfs::FileSystem;
 
-use system::scheme::{Packet, Scheme};
+use syscall::{Packet, Scheme};
 
 pub mod cache;
 pub mod image;
@@ -43,9 +43,9 @@ fn main() {
                         Ok(mut socket) => {
                             println!("redoxfs: mounted filesystem {} on file:", path);
 
-                            *status_daemon.lock().unwrap() = Status::Running;
+                            *status_daemon.lock() = Status::Running;
 
-                            let mut scheme = FileScheme::new(fs);
+                            let scheme = FileScheme::new(fs);
                             loop {
                                 let mut packet = Packet::default();
                                 while socket.read(&mut packet).unwrap() == size_of::<Packet>() {
@@ -61,17 +61,17 @@ fn main() {
                 Err(err) => println!("redoxfs: failed to open image {}: {}", path, err)
             }
 
-            *status_daemon.lock().unwrap() = Status::Stopping;
+            *status_daemon.lock() = Status::Stopping;
         });
 
         'waiting: loop {
-            match *status_mutex.lock().unwrap() {
+            match *status_mutex.lock() {
                 Status::Starting => (),
                 Status::Running => break 'waiting,
                 Status::Stopping => break 'waiting,
             }
 
-            thread::sleep(Duration::new(0, 30000000));
+            thread::yield_now();
         }
     } else {
         println!("redoxfs: no disk image provided");
diff --git a/scheme/resource.rs b/scheme/resource.rs
index 9f4071302e7d64c0804cd5f329096797801ab0c3..4a584eba5f1569ee6afd214d23fab60b69b9d448 100644
--- a/scheme/resource.rs
+++ b/scheme/resource.rs
@@ -2,8 +2,8 @@ use redoxfs::FileSystem;
 
 use std::cmp::{min, max};
 
-use system::error::{Error, Result, EINVAL};
-use system::syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END, MODE_DIR, MODE_FILE};
+use syscall::error::{Error, Result, EINVAL};
+use syscall::{Stat, SEEK_SET, SEEK_CUR, SEEK_END, MODE_DIR, MODE_FILE};
 
 pub trait Resource {
     fn dup(&self) -> Result<Box<Resource>>;
@@ -17,15 +17,15 @@ pub trait Resource {
 }
 
 pub struct DirResource {
-    path: String,
+    path: Vec<u8>,
     data: Vec<u8>,
     seek: usize,
 }
 
 impl DirResource {
-    pub fn new(path: &str, data: Vec<u8>) -> DirResource {
+    pub fn new(path: &[u8], data: Vec<u8>) -> DirResource {
         DirResource {
-            path: path.to_string(),
+            path: path.to_vec(),
             data: data,
             seek: 0,
         }
@@ -67,9 +67,8 @@ impl Resource for DirResource {
 
     fn path(&self, buf: &mut [u8]) -> Result<usize> {
         let mut i = 0;
-        let path = self.path.as_bytes();
-        while i < buf.len() && i < path.len() {
-            buf[i] = path[i];
+        while i < buf.len() && i < self.path.len() {
+            buf[i] = self.path[i];
             i += 1;
         }
         Ok(i)
@@ -91,16 +90,16 @@ impl Resource for DirResource {
 }
 
 pub struct FileResource {
-    path: String,
+    path: Vec<u8>,
     block: u64,
     seek: u64,
     size: u64,
 }
 
 impl FileResource {
-    pub fn new(path: &str, block: u64, size: u64) -> FileResource {
+    pub fn new(path: &[u8], block: u64, size: u64) -> FileResource {
         FileResource {
-            path: path.to_string(),
+            path: path.to_vec(),
             block: block,
             seek: 0,
             size: size,
@@ -146,9 +145,8 @@ impl Resource for FileResource {
 
     fn path(&self, buf: &mut [u8]) -> Result<usize> {
         let mut i = 0;
-        let path = self.path.as_bytes();
-        while i < buf.len() && i < path.len() {
-            buf[i] = path[i];
+        while i < buf.len() && i < self.path.len() {
+            buf[i] = self.path[i];
             i += 1;
         }
         Ok(i)
diff --git a/scheme/scheme.rs b/scheme/scheme.rs
index 7deb198b79f6812cc6e7d661047d61db07d5e0af..627ced349fa4902d8272f72c0680ee7443f0e138 100644
--- a/scheme/scheme.rs
+++ b/scheme/scheme.rs
@@ -1,41 +1,46 @@
 use resource::{Resource, DirResource, FileResource};
 
 use redoxfs::{FileSystem, Node};
-
+use spin::Mutex;
+use std::cell::RefCell;
 use std::collections::BTreeMap;
+use std::str;
+use std::sync::atomic::{AtomicUsize, Ordering};
 
-use system::error::{Error, Result, EEXIST, EISDIR, ENOTDIR, EPERM, ENOENT, EBADF};
-use system::scheme::Scheme;
-use system::syscall::{Stat, O_CREAT, O_TRUNC};
+use syscall::error::{Error, Result, EEXIST, EISDIR, ENOTDIR, EPERM, ENOENT, EBADF};
+use syscall::scheme::Scheme;
+use syscall::{Stat, O_CREAT, O_TRUNC};
 
 pub struct FileScheme {
-    fs: FileSystem,
-    next_id: isize,
-    files: BTreeMap<usize, Box<Resource>>
+    fs: RefCell<FileSystem>,
+    next_id: AtomicUsize,
+    files: Mutex<BTreeMap<usize, Box<Resource>>>
 }
 
 impl FileScheme {
     pub fn new(fs: FileSystem) -> FileScheme {
         FileScheme {
-            fs: fs,
-            next_id: 1,
-            files: BTreeMap::new()
+            fs: RefCell::new(fs),
+            next_id: AtomicUsize::new(1),
+            files: Mutex::new(BTreeMap::new())
         }
     }
 
-    fn open_inner(&mut self, url: &str, flags: usize) -> Result<Box<Resource>> {
-        let path = url.split(':').nth(1).unwrap_or("").trim_matches('/');
+    fn open_inner(&self, url: &[u8], flags: usize) -> Result<Box<Resource>> {
+        let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
 
         // println!("Open '{}' {:X}", path, flags);
 
+        let mut fs = self.fs.borrow_mut();
+
         let mut nodes = Vec::new();
-        let node_result = self.fs.path_nodes(path, &mut nodes);
+        let node_result = fs.path_nodes(path, &mut nodes);
 
         match node_result {
             Ok(node) => if node.1.is_dir() {
                 let mut data = Vec::new();
                 let mut children = Vec::new();
-                try!(self.fs.child_nodes(&mut children, node.0));
+                try!(fs.child_nodes(&mut children, node.0));
                 for child in children.iter() {
                     if let Ok(name) = child.1.name() {
                         if ! data.is_empty() {
@@ -51,9 +56,9 @@ impl FileScheme {
             } else {
                 if flags & O_TRUNC == O_TRUNC {
                     // println!("Truncate {}", path);
-                    try!(self.fs.node_set_len(node.0, 0));
+                    try!(fs.node_set_len(node.0, 0));
                 }
-                let size = try!(self.fs.node_len(node.0));
+                let size = try!(fs.node_len(node.0));
                 return Ok(Box::new(FileResource::new(url, node.0, size)));
             },
             Err(err) => if err.errno == ENOENT && flags & O_CREAT == O_CREAT {
@@ -65,7 +70,7 @@ impl FileScheme {
                 }
                 if ! last_part.is_empty() {
                     if let Some(parent) = nodes.last() {
-                        let node = try!(self.fs.create_node(Node::MODE_FILE, &last_part, parent.0));
+                        let node = try!(fs.create_node(Node::MODE_FILE, &last_part, parent.0));
                         return Ok(Box::new(FileResource::new(url, node.0, 0)));
                     } else {
                         return Err(Error::new(EPERM));
@@ -81,27 +86,24 @@ impl FileScheme {
 }
 
 impl Scheme for FileScheme {
-    fn open(&mut self, url: &str, flags: usize) -> Result<usize> {
+    fn open(&self, url: &[u8], flags: usize) -> Result<usize> {
         let resource = try!(self.open_inner(url, flags));
 
-        let id = self.next_id as usize;
-        self.next_id += 1;
-        if self.next_id < 0 {
-            self.next_id = 1;
-        }
-
-        self.files.insert(id, resource);
+        let id = self.next_id.fetch_add(1, Ordering::SeqCst);
+        self.files.lock().insert(id, resource);
 
         Ok(id)
     }
 
-    fn mkdir(&mut self, url: &str, _mode: usize) -> Result<usize> {
-        let path = url.split(':').nth(1).unwrap_or("").trim_matches('/');
+    fn mkdir(&self, url: &[u8], _mode: usize) -> Result<usize> {
+        let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
 
         // println!("Mkdir '{}'", path);
 
+        let mut fs = self.fs.borrow_mut();
+
         let mut nodes = Vec::new();
-        match self.fs.path_nodes(path, &mut nodes) {
+        match fs.path_nodes(path, &mut nodes) {
             Ok(_node) => Err(Error::new(EEXIST)),
             Err(err) => if err.errno == ENOENT {
                 let mut last_part = String::new();
@@ -112,7 +114,7 @@ impl Scheme for FileScheme {
                 }
                 if ! last_part.is_empty() {
                     if let Some(parent) = nodes.last() {
-                        self.fs.create_node(Node::MODE_DIR, &last_part, parent.0).and(Ok(0))
+                        fs.create_node(Node::MODE_DIR, &last_part, parent.0).and(Ok(0))
                     } else {
                         Err(Error::new(EPERM))
                     }
@@ -125,17 +127,19 @@ impl Scheme for FileScheme {
         }
     }
 
-    fn rmdir(&mut self, url: &str) -> Result<usize> {
-        let path = url.split(':').nth(1).unwrap_or("").trim_matches('/');
+    fn rmdir(&self, url: &[u8]) -> Result<usize> {
+        let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
 
         // println!("Rmdir '{}'", path);
 
+        let mut fs = self.fs.borrow_mut();
+
         let mut nodes = Vec::new();
-        let child = try!(self.fs.path_nodes(path, &mut nodes));
+        let child = try!(fs.path_nodes(path, &mut nodes));
         if let Some(parent) = nodes.last() {
             if child.1.is_dir() {
                 if let Ok(child_name) = child.1.name() {
-                    self.fs.remove_node(Node::MODE_DIR, child_name, parent.0).and(Ok(0))
+                    fs.remove_node(Node::MODE_DIR, child_name, parent.0).and(Ok(0))
                 } else {
                     Err(Error::new(ENOENT))
                 }
@@ -147,22 +151,19 @@ impl Scheme for FileScheme {
         }
     }
 
-    fn stat(&mut self, url: &str, stat: &mut Stat) -> Result<usize> {
-        let resource = try!(self.open_inner(url, 0));
-        resource.stat(stat)
-    }
-
-    fn unlink(&mut self, url: &str) -> Result<usize> {
-        let path = url.split(':').nth(1).unwrap_or("").trim_matches('/');
+    fn unlink(&self, url: &[u8]) -> Result<usize> {
+        let path = str::from_utf8(url).unwrap_or("").trim_matches('/');
 
         // println!("Unlink '{}'", path);
 
+        let mut fs = self.fs.borrow_mut();
+
         let mut nodes = Vec::new();
-        let child = try!(self.fs.path_nodes(path, &mut nodes));
+        let child = try!(fs.path_nodes(path, &mut nodes));
         if let Some(parent) = nodes.last() {
             if ! child.1.is_dir() {
                 if let Ok(child_name) = child.1.name() {
-                    self.fs.remove_node(Node::MODE_FILE, child_name, parent.0).and(Ok(0))
+                    fs.remove_node(Node::MODE_FILE, child_name, parent.0).and(Ok(0))
                 } else {
                     Err(Error::new(ENOENT))
                 }
@@ -176,44 +177,43 @@ impl Scheme for FileScheme {
 
     /* Resource operations */
     #[allow(unused_variables)]
-    fn dup(&mut self, old_id: usize) -> Result<usize> {
+    fn dup(&self, old_id: usize) -> Result<usize> {
         // println!("Dup {}", old_id);
 
-        let resource = try!(try!(self.files.get(&old_id).ok_or(Error::new(EBADF))).dup());
-
-        let id = self.next_id as usize;
-        self.next_id += 1;
-        if self.next_id < 0 {
-            self.next_id = 1;
-        }
+        let mut files = self.files.lock();
+        let resource = try!(try!(files.get(&old_id).ok_or(Error::new(EBADF))).dup());
 
-        self.files.insert(id, resource);
+        let id = self.next_id.fetch_add(1, Ordering::SeqCst);
+        files.insert(id, resource);
 
         Ok(id)
     }
 
     #[allow(unused_variables)]
-    fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
+    fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
         // println!("Read {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
-        if let Some(mut file) = self.files.get_mut(&id) {
-            file.read(buf, &mut self.fs)
+        let mut files = self.files.lock();
+        if let Some(mut file) = files.get_mut(&id) {
+            file.read(buf, &mut self.fs.borrow_mut())
         } else {
             Err(Error::new(EBADF))
         }
     }
 
-    fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
+    fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
         // println!("Write {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
-        if let Some(mut file) = self.files.get_mut(&id) {
-            file.write(buf, &mut self.fs)
+        let mut files = self.files.lock();
+        if let Some(mut file) = files.get_mut(&id) {
+            file.write(buf, &mut self.fs.borrow_mut())
         } else {
             Err(Error::new(EBADF))
         }
     }
 
-    fn seek(&mut self, id: usize, pos: usize, whence: usize) -> Result<usize> {
+    fn seek(&self, id: usize, pos: usize, whence: usize) -> Result<usize> {
         // println!("Seek {}, {} {}", id, pos, whence);
-        if let Some(mut file) = self.files.get_mut(&id) {
+        let mut files = self.files.lock();
+        if let Some(mut file) = files.get_mut(&id) {
             file.seek(pos, whence)
         } else {
             Err(Error::new(EBADF))
@@ -222,7 +222,8 @@ impl Scheme for FileScheme {
 
     fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
         // println!("Fpath {}, {:X} {}", id, buf.as_ptr() as usize, buf.len());
-        if let Some(file) = self.files.get(&id) {
+        let files = self.files.lock();
+        if let Some(file) = files.get(&id) {
             file.path(buf)
         } else {
             Err(Error::new(EBADF))
@@ -231,34 +232,38 @@ impl Scheme for FileScheme {
 
     fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
         // println!("Fstat {}, {:X}", id, stat as *mut Stat as usize);
-        if let Some(file) = self.files.get(&id) {
+        let files = self.files.lock();
+        if let Some(file) = files.get(&id) {
             file.stat(stat)
         } else {
             Err(Error::new(EBADF))
         }
     }
 
-    fn fsync(&mut self, id: usize) -> Result<usize> {
+    fn fsync(&self, id: usize) -> Result<usize> {
         // println!("Fsync {}", id);
-        if let Some(mut file) = self.files.get_mut(&id) {
+        let mut files = self.files.lock();
+        if let Some(mut file) = files.get_mut(&id) {
             file.sync()
         } else {
             Err(Error::new(EBADF))
         }
     }
 
-    fn ftruncate(&mut self, id: usize, len: usize) -> Result<usize> {
+    fn ftruncate(&self, id: usize, len: usize) -> Result<usize> {
         // println!("Ftruncate {}, {}", id, len);
-        if let Some(mut file) = self.files.get_mut(&id) {
-            file.truncate(len, &mut self.fs)
+        let mut files = self.files.lock();
+        if let Some(mut file) = files.get_mut(&id) {
+            file.truncate(len, &mut self.fs.borrow_mut())
         } else {
             Err(Error::new(EBADF))
         }
     }
 
-    fn close(&mut self, id: usize) -> Result<usize> {
+    fn close(&self, id: usize) -> Result<usize> {
         // println!("Close {}", id);
-        if self.files.remove(&id).is_some() {
+        let mut files = self.files.lock();
+        if files.remove(&id).is_some() {
             Ok(0)
         } else {
             Err(Error::new(EBADF))
diff --git a/src/disk.rs b/src/disk.rs
index 75a9e58ae8c064608e0259b595c50801ebc8c42d..e345ee82cfa71b6bc7809d3223a2639cb81b76aa 100644
--- a/src/disk.rs
+++ b/src/disk.rs
@@ -1,4 +1,4 @@
-use system::error::Result;
+use syscall::error::Result;
 
 /// A disk
 pub trait Disk {
diff --git a/src/filesystem.rs b/src/filesystem.rs
index bd2b96c8bf55dc657e734c81e4f74fc125170354..1c36f83b29dda73ca643fd4ffb850545e405cdb3 100644
--- a/src/filesystem.rs
+++ b/src/filesystem.rs
@@ -1,6 +1,6 @@
 use std::cmp::min;
 
-use system::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY};
+use syscall::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY};
 
 use super::{Disk, ExNode, Extent, Header, Node};
 
diff --git a/src/lib.rs b/src/lib.rs
index fcf352966f4137b3547951ec516c085fab620f4e..f4106c3994d2726411638b20f19b2d64833f0314 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,7 +4,7 @@
 
 #![deny(warnings)]
 
-extern crate system;
+extern crate syscall;
 
 pub use self::disk::Disk;
 pub use self::ex_node::ExNode;