diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs
index 4400c8d87c12c712529d9c5d89c7adbe51d180f2..ba6e0f0e8cba2291ea4e2481e87efe47e0fdef4f 100644
--- a/src/acpi/aml/dataobj.rs
+++ b/src/acpi/aml/dataobj.rs
@@ -1,131 +1,134 @@
 use collections::vec::Vec;
 use collections::string::String;
 
-use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, get_namespace_string};
-
-use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package,
-                         DefBuffer, DefPackage, DefVarPackage};
-use super::termlist::{parse_term_arg, TermArg};
-use super::namestring::{parse_super_name, SuperName};
-
-#[derive(Debug, Clone)]
-pub enum DataObj {
-    ComputationalData(ComputationalData),
-    DefPackage(DefPackage),
-    DefVarPackage(DefVarPackage)
-}
-
-#[derive(Debug, Clone)]
-pub enum DataRefObj {
-    DataObj(DataObj),
-    ObjectReference(TermArg),
-    DDBHandle(SuperName)
-}
-
-#[derive(Debug, Clone)]
-pub struct ArgObj(u8);
-#[derive(Debug, Clone)]
-pub struct LocalObj(u8);
-// Not actually doing anything to contain data, but does give us type guarantees, which is useful
-
-#[derive(Debug, Clone)]
-pub enum ComputationalData {
-    Byte(u8),
-    Word(u16),
-    DWord(u32),
-    QWord(u64),
-    String(String),
-    Zero,
-    One,
-    Ones,
-    DefBuffer(DefBuffer),
-    RevisionOp
-}
-
-impl AmlExecutable for DataRefObj {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            DataRefObj::DataObj(ref cd) => cd.execute(namespace, scope),
-            _ => Some(AmlValue::Integer)
-        }
-    }
-}
-
-impl AmlExecutable for DataObj {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            DataObj::ComputationalData(ref cd) => cd.execute(namespace, scope),
-            DataObj::DefPackage(ref pkg) => pkg.execute(namespace, scope),
-            _ => Some(AmlValue::Integer)
-        }
+use super::AmlError;
+use super::parser::{ AmlParseType, ParseResult, AmlExecutionContext, ExecutionState };
+use super::namespace::{ AmlValue, ObjectReference };
+
+use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package};
+use super::termlist::parse_term_arg;
+use super::namestring::parse_super_name;
+
+pub fn parse_data_obj(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
-}
-
-impl AmlExecutable for ComputationalData {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            ComputationalData::Byte(b) => Some(AmlValue::IntegerConstant(b as u64)),
-            ComputationalData::Word(w) => Some(AmlValue::IntegerConstant(w as u64)),
-            ComputationalData::DWord(d) => Some(AmlValue::IntegerConstant(d as u64)),
-            ComputationalData::QWord(q) => Some(AmlValue::IntegerConstant(q as u64)),
-            ComputationalData::Zero => Some(AmlValue::IntegerConstant(0)),
-            ComputationalData::One => Some(AmlValue::IntegerConstant(1)),
-            ComputationalData::Ones => Some(AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF)),
-            _ => Some(AmlValue::Integer)
-        }
-    }
-}
-
-pub fn parse_data_obj(data: &[u8]) -> Result<(DataObj, usize), AmlInternalError> {
+    
     parser_selector! {
-        data,
-        parser_wrap!(DataObj::ComputationalData, parse_computational_data),
-        parser_wrap!(DataObj::DefPackage, parse_def_package),
-        parser_wrap!(DataObj::DefVarPackage, parse_def_var_package)
+        data, ctx,
+        parse_computational_data,
+        parse_def_package,
+        parse_def_var_package
     };
     
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_data_ref_obj(data: &[u8]) -> Result<(DataRefObj, usize), AmlInternalError> {
+pub fn parse_data_ref_obj(data: &[u8],
+                          ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
-        parser_wrap!(DataRefObj::DataObj, parse_data_obj),
-        parser_wrap!(DataRefObj::ObjectReference, parse_term_arg),
-        parser_wrap!(DataRefObj::DDBHandle, parse_super_name)
+        data, ctx,
+        parse_data_obj,
+        parse_term_arg
     };
     
-    Err(AmlInternalError::AmlInvalidOpCode)
+    match parse_super_name(data, ctx) {
+        Ok(res) => match res.val {
+            AmlValue::String(s) => Ok(AmlParseType {
+                val: AmlValue::ObjectReference(ObjectReference::Object(s)),
+                len: res.len
+            }),
+            _ => Ok(res)
+        },
+        Err(e) => Err(e)
+    }
 }
 
-pub fn parse_arg_obj(data: &[u8]) -> Result<(ArgObj, usize), AmlInternalError> {
+pub fn parse_arg_obj(data: &[u8],
+                     ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     match data[0] {
-        0x68 ... 0x6E => Ok((ArgObj(data[0] - 0x68), 1 as usize)),
-        _ => Err(AmlInternalError::AmlInvalidOpCode)
+        0x68 ... 0x6E => Ok(AmlParseType {
+            val: AmlValue::ObjectReference(ObjectReference::ArgObj(data[0] - 0x68)),
+            len: 1 as usize
+        }),
+        _ => Err(AmlError::AmlInvalidOpCode)
     }
 }
 
-pub fn parse_local_obj(data: &[u8]) -> Result<(LocalObj, usize), AmlInternalError> {
+pub fn parse_local_obj(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     match data[0] {
-        0x60 ... 0x67 => Ok((LocalObj(data[0] - 0x60), 1 as usize)),
-        _ => Err(AmlInternalError::AmlInvalidOpCode)
+        0x68 ... 0x6E => Ok(AmlParseType {
+            val: AmlValue::ObjectReference(ObjectReference::LocalObj(data[0] - 0x60)),
+            len: 1 as usize
+        }),
+        _ => Err(AmlError::AmlInvalidOpCode)
     }
 }
 
-fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), AmlInternalError> {
+fn parse_computational_data(data: &[u8],
+                            ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     match data[0] {
-        0x0A => Ok((ComputationalData::Byte(data[1]), 2 as usize)),
+        0x0A => Ok(AmlParseType {
+            val: AmlValue::Integer(data[1] as u64),
+            len: 2 as usize
+        }),
         0x0B => {
             let res = (data[1] as u16) +
                 ((data[2] as u16) << 8);
-            Ok((ComputationalData::Word(res), 3 as usize))
+
+            Ok(AmlParseType {
+                val: AmlValue::Integer(res as u64),
+                len: 3 as usize
+            })
         },
         0x0C => {
             let res = (data[1] as u32) +
                 ((data[2] as u32) << 8) +
                 ((data[3] as u32) << 16) +
                 ((data[4] as u32) << 24);
-            Ok((ComputationalData::DWord(res), 5 as usize))
+
+            Ok(AmlParseType {
+                val: AmlValue::Integer(res as u64),
+                len: 5 as usize
+            })
         },
         0x0D => {
             let mut cur_ptr: usize = 1;
@@ -137,8 +140,11 @@ fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), A
             }
 
             match String::from_utf8(cur_string) {
-                Ok(s) => Ok((ComputationalData::String(s.clone()), s.clone().len() + 2)),
-                Err(_) => Err(AmlInternalError::AmlParseError("String data - invalid string"))
+                Ok(s) => Ok(AmlParseType {
+                    val: AmlValue::String(s.clone()),
+                    len: s.clone().len() + 2
+                }),
+                Err(_) => Err(AmlError::AmlParseError("String data - invalid string"))
             }
         },
         0x0E => {
@@ -150,19 +156,32 @@ fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), A
                 ((data[6] as u64) << 40) +
                 ((data[7] as u64) << 48) +
                 ((data[8] as u64) << 56);
-            Ok((ComputationalData::QWord(res), 9 as usize))
+
+            Ok(AmlParseType {
+                val: AmlValue::Integer(res as u64),
+                len: 9 as usize
+            })
         },
-        0x00 => Ok((ComputationalData::Zero, 1 as usize)),
-        0x01 => Ok((ComputationalData::One, 1 as usize)),
+        0x00 => Ok(AmlParseType {
+            val: AmlValue::IntegerConstant(0 as u64),
+            len: 1 as usize
+        }),
+        0x01 => Ok(AmlParseType {
+            val: AmlValue::IntegerConstant(1 as u64),
+            len: 1 as usize
+        }),
         0x5B => if data[1] == 0x30 {
-            Ok((ComputationalData::RevisionOp, 2 as usize))
+            Ok(AmlParseType {
+                val: AmlValue::IntegerConstant(20170630 as u64),
+                len: 2 as usize
+            })
         } else {
-            Err(AmlInternalError::AmlInvalidOpCode)
+            Err(AmlError::AmlInvalidOpCode)
         },
-        0xFF => Ok((ComputationalData::Ones, 1 as usize)),
-        _ => match parse_def_buffer(data) {
-            Ok((res, size)) => Ok((ComputationalData::DefBuffer(res), size)),
-            Err(e) => Err(e)
-        }
+        0xFF => Ok(AmlParseType {
+            val: AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF),
+            len: 1 as usize
+        }),
+        _ => parse_def_buffer(data, ctx)
     }
 }
diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs
index 296317d021b5568278343e64f201e49f22df2803..9ec105c625a587713062f705f34636fc57c0efee 100644
--- a/src/acpi/aml/mod.rs
+++ b/src/acpi/aml/mod.rs
@@ -1,10 +1,8 @@
 //! # AML
 //! Code to parse and execute AML tables
 
-use alloc::boxed::Box;
 use collections::string::String;
 use collections::vec::Vec;
-use core::fmt::Debug;
 use core::str::FromStr;
 
 use super::sdt::Sdt;
@@ -21,63 +19,37 @@ mod namedobj;
 mod dataobj;
 mod type1opcode;
 mod type2opcode;
+mod parser;
 
-use self::termlist::{parse_term_list, TermObj};
-pub use self::namespace::{AmlNamespace, AmlValue};
-use self::namespace::AmlNamespaceContents;
+use self::parser::AmlExecutionContext;
+use self::termlist::parse_term_list;
+pub use self::namespace::AmlValue;
 
-// TODO: This should be able to take parameters, and may also return multiple values
-pub trait AmlExecutable {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue>;
-}
-
-// TODO: make private
-pub enum AmlInternalError {
+#[derive(Debug)]
+pub enum AmlError {
     AmlParseError(&'static str),
     AmlInvalidOpCode,
-    AmlDeferredLoad
+    AmlValueError,
+    AmlDeferredLoad,
+    AmlFatalError(u8, u16, AmlValue),
+    AmlHardFatal
 }
 
-pub enum AmlError {
-    AmlParseError(&'static str)
+pub fn parse_aml_table(sdt: &Sdt) -> Result<Vec<String>, AmlError> {
+    parse_aml_with_scope(sdt, String::from_str("\\").unwrap())
 }
 
-pub fn get_namespace_string(current: String, modifier: String) -> String {
-    if modifier.starts_with("\\") {
-        return modifier;
-    }
-
-    if modifier.starts_with("^") {
-        // TODO
-    }
-
-    let mut namespace = current.clone();
-    namespace.push('.');
-    namespace + &modifier
-}
-
-pub fn parse_aml_table(sdt: &'static Sdt) -> Result<AmlNamespace, AmlError> {
+pub fn parse_aml_with_scope(sdt: &Sdt, scope: String) -> Result<Vec<String>, AmlError> {
     let data = sdt.data();
+    let mut ctx = AmlExecutionContext::new(scope);
+    
+    parse_term_list(data, &mut ctx)?;
 
-    let term_list = match parse_term_list(data) {
-        Ok(res) => res,
-        Err(AmlInternalError::AmlParseError(s)) => return Err(AmlError::AmlParseError(s)),
-        Err(AmlInternalError::AmlInvalidOpCode) => return Err(AmlError::AmlParseError("Unable to match opcode")),
-        Err(AmlInternalError::AmlDeferredLoad) => return Err(AmlError::AmlParseError("Deferred load reached top level"))
-    };
-
-    let global_namespace_specifier = String::from_str("\\").unwrap();
-    // Unwrap is fine here. I mean come on, if this goes wrong you've got bigger problems than AML
-    // not loading...
-
-    let mut global_namespace = AmlNamespace::new_namespace(&global_namespace_specifier);
-    term_list.execute(&mut global_namespace, global_namespace_specifier.clone());
-
-    Ok(global_namespace)
+    Ok(ctx.namespace_delta)
 }
 
-pub fn is_aml_table(sdt: &'static Sdt) -> bool {
-    if &sdt.signature == b"DSDT" {//|| &sdt.signature == b"SSDT" {
+pub fn is_aml_table(sdt: &Sdt) -> bool {
+    if &sdt.signature == b"DSDT" || &sdt.signature == b"SSDT" {
         true
     } else {
         false
diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs
index 26cca7b0ed69712a384bf86ffe7dfc46718421da..bd813a8edbdaf476c79c8721a5430fcc8ed22bf0 100644
--- a/src/acpi/aml/namedobj.rs
+++ b/src/acpi/aml/namedobj.rs
@@ -1,174 +1,16 @@
 use alloc::boxed::Box;
 use collections::string::String;
-use collections::vec::Vec;
+use collections::btree_map::BTreeMap;
 
-use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, AmlNamespaceContents, get_namespace_string};
+use super::AmlError;
+use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext, ExecutionState };
+use super::namespace::{AmlValue, ObjectReference, FieldSelector, Method, get_namespace_string,
+                       Accessor, BufferField, FieldUnit, Processor, PowerResource, OperationRegion,
+                       Device, ThermalZone};
 use super::namestring::{parse_name_string, parse_name_seg};
-use super::termlist::{parse_term_arg, parse_term_list, parse_object_list, TermArg, TermObj, Object};
+use super::termlist::{parse_term_arg, parse_object_list};
 use super::pkglength::parse_pkg_length;
-use super::type2opcode::{parse_def_buffer, DefBuffer};
-
-#[derive(Debug, Clone)]
-pub enum NamedObj {
-    DefBankField {
-        region_name: String,
-        bank_name: String,
-        bank_value: TermArg,
-        flags: FieldFlags,
-        field_list: Vec<FieldElement>
-    },
-    DefCreateBitField {
-        name: String,
-        source_buf: TermArg,
-        bit_index: TermArg
-    },
-    DefCreateByteField {
-        name: String,
-        source_buf: TermArg,
-        byte_index: TermArg
-    },
-    DefCreateWordField {
-        name: String,
-        source_buf: TermArg,
-        byte_index: TermArg
-    },
-    DefCreateDWordField {
-        name: String,
-        source_buf: TermArg,
-        byte_index: TermArg
-    },
-    DefCreateQWordField {
-        name: String,
-        source_buf: TermArg,
-        byte_index: TermArg
-    },
-    DefCreateField {
-        name: String,
-        source_buf: TermArg,
-        bit_index: TermArg,
-        num_bits: TermArg
-    },
-    DefDataRegion {
-        name: String,
-        signature: TermArg,
-        oem_id: TermArg,
-        oem_table_id: TermArg
-    },
-    DefDevice {
-        name: String,
-        obj_list: Vec<Object>
-    },
-    DefEvent {
-        name: String
-    },
-    DefOpRegion {
-        name: String,
-        region: RegionSpace,
-        offset: TermArg,
-        len: TermArg
-    },
-    DefField {
-        name: String,
-        flags: FieldFlags,
-        field_list: Vec<FieldElement>
-    },
-    DefIndexField {
-        idx_name: String,
-        data_name: String,
-        flags: FieldFlags,
-        field_list: Vec<FieldElement>
-    },
-    DefMethod {
-        name: String,
-        method: Method
-    },
-    DefMutex {
-        name: String,
-        sync_level: u8
-    },
-    DefPowerRes {
-        name: String,
-        system_level: u8,
-        resource_order: u16,
-        obj_list: Vec<Object>
-    },
-    DefProcessor {
-        name: String,
-        proc_id: u8,
-        p_blk_addr: u32,
-        p_blk_len: u8,
-        obj_list: Vec<Object>
-    },
-    DefThermalZone {
-        name: String,
-        obj_list: Vec<Object>
-    },
-    DeferredLoad(Vec<u8>)
-}
-
-#[derive(Debug, Clone)]
-pub struct Method {
-    arg_count: u8,
-    serialized: bool,
-    sync_level: u8,
-    term_list: Vec<TermObj>
-}
-
-impl AmlExecutable for NamedObj {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => {
-                let local_scope_string = get_namespace_string(scope.clone(), name.clone());
-
-                let resolved_offset = match offset.execute(namespace, scope.clone()) {
-                    Some(r) => r,
-                    _ => return None
-                };
-
-                let resolved_len = match len.execute(namespace, scope.clone()) {
-                    Some(r) => r,
-                    _ => return None
-                };
-
-                namespace.push_to(local_scope_string, AmlNamespaceContents::OpRegion {
-                    region: *region,
-                    offset: resolved_offset,
-                    len: resolved_len
-                });
-            },
-            NamedObj::DefField { ref name, ref flags, ref field_list } => {
-                let mut offset: usize = 0;
-
-                for f in field_list {
-                    match *f {
-                        FieldElement::ReservedField { length } => offset += length,
-                        FieldElement::NamedField { name: ref field_name, length } => {
-                            let local_scope_string = get_namespace_string(scope.clone(),
-                                                                          field_name.clone());
-                            namespace.push_to(local_scope_string, AmlNamespaceContents::Field {
-                                op_region: name.clone(),
-                                flags: flags.clone(),
-                                offset: offset.clone(),
-                                length: length.clone()
-                            });
-
-                            offset += length;
-                        },
-                        _ => ()
-                    }
-                }
-            },
-            NamedObj::DefMethod { ref name, ref method } => {
-                let local_scope_string = get_namespace_string(scope.clone(), name.clone());
-                namespace.push_to(local_scope_string, AmlNamespaceContents::Value(
-                                  AmlValue::Method(method.clone())));
-            },
-            _ => ()
-        }
-
-        None
-    }
-}
+use super::type2opcode::parse_def_buffer;
 
 #[derive(Debug, Copy, Clone)]
 pub enum RegionSpace {
@@ -199,7 +41,7 @@ pub enum AccessType {
     WordAcc,
     DWordAcc,
     QWordAcc,
-    BufferAcc
+    BufferAcc(AccessAttrib)
 }
 
 #[derive(Debug, Clone)]
@@ -210,20 +52,15 @@ pub enum UpdateRule {
 }
 
 #[derive(Debug, Clone)]
-pub enum FieldElement {
-    NamedField {
-        name: String,
-        length: usize
-    },
-    ReservedField {
-        length: usize
-    },
-    AccessField {
-        access_type: AccessType,
-        access_attrib: AccessAttrib
-    },
-    ConnectFieldNameString(String),
-    ConnectFieldBufferData(DefBuffer),
+pub struct NamedField {
+    name: String,
+    length: usize
+}
+
+#[derive(Debug, Clone)]
+pub struct AccessField {
+    access_type: AccessType,
+    access_attrib: AccessAttrib
 }
 
 #[derive(Debug, Clone)]
@@ -240,9 +77,18 @@ pub enum AccessAttrib {
     AttribBlockProcessCall
 }
 
-pub fn parse_named_obj(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+pub fn parse_named_obj(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
+        data, ctx,
         parse_def_bank_field,
         parse_def_create_bit_field,
         parse_def_create_byte_field,
@@ -252,6 +98,7 @@ pub fn parse_named_obj(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErro
         parse_def_create_field,
         parse_def_data_region,
         parse_def_event,
+        parse_def_external,
         parse_def_device,
         parse_def_op_region,
         parse_def_field,
@@ -263,185 +110,351 @@ pub fn parse_named_obj(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErro
         parse_def_thermal_zone
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-fn parse_def_bank_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+fn parse_def_bank_field(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x87);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
-    let (region_name, region_name_len) = match parse_name_string(
-            &data[2 + pkg_length_len .. 2 + pkg_length]) {
-        Ok(res) => res,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-
-    let (bank_name, bank_name_len) = match parse_name_string(
-            &data[2 + pkg_length_len + region_name_len .. 2 + pkg_length]) {
-        Ok(res) => res,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
+    let data = &data[2 + pkg_length_len .. 2 + pkg_length];
+    
+    let region_name = parse_name_string(data, ctx)?;
+    let bank_name = parse_name_string(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], ctx)?;
 
-    let (bank_value, bank_value_len) = match parse_term_arg(
-            &data[2 + pkg_length_len + region_name_len .. 2 + pkg_length]) {
-        Ok(res) => res,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
+    let bank_value = parse_term_arg(&data[2 + pkg_length_len + region_name.len .. 2 + pkg_length], ctx)?;
 
-    let flags_raw = data[2 + pkg_length_len + region_name_len + bank_name_len + bank_value_len];
-    let flags = FieldFlags {
+    let flags_raw = data[2 + pkg_length_len + region_name.len + bank_name.len + bank_value.len];
+    let mut flags = FieldFlags {
         access_type: match flags_raw & 0x0F {
             0 => AccessType::AnyAcc,
             1 => AccessType::ByteAcc,
             2 => AccessType::WordAcc,
             3 => AccessType::DWordAcc,
             4 => AccessType::QWordAcc,
-            5 => AccessType::BufferAcc,
-            _ => return Err(AmlInternalError::AmlParseError("BankField - invalid access type"))
+            5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
+            _ => return Err(AmlError::AmlParseError("BankField - invalid access type"))
         },
         lock_rule: (flags_raw & 0x10) == 0x10,
         update_rule: match (flags_raw & 0x60) >> 5 {
             0 => UpdateRule::Preserve,
             1 => UpdateRule::WriteAsOnes,
             2 => UpdateRule::WriteAsZeros,
-            _ => return Err(AmlInternalError::AmlParseError("BankField - invalid update rule"))
+            _ => return Err(AmlError::AmlParseError("BankField - invalid update rule"))
         }
     };
 
-    let field_list = match parse_field_list(
-        &data[3 + pkg_length_len + region_name_len + bank_name_len + bank_value_len ..
-              2 + pkg_length]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
+    let selector = FieldSelector::Bank {
+        region: region_name.val.get_as_string()?,
+        bank_register: bank_name.val.get_as_string()?,
+        bank_selector: Box::new(bank_value.val)
     };
 
-    Ok((NamedObj::DefBankField {region_name, bank_name, bank_value, flags, field_list},
-        2 + pkg_length))
+    parse_field_list(&data[3 + pkg_length_len + region_name.len + bank_name.len + bank_value.len ..
+                           2 + pkg_length], ctx, selector, &mut flags)?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_length
+    })
 }
 
-fn parse_def_create_bit_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+fn parse_def_create_bit_field(data: &[u8],
+                              ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x8D);
 
-    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
-    let (bit_index, bit_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
-    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + bit_index_len..])?;
-
-    Ok((NamedObj::DefCreateBitField {name, source_buf, bit_index},
-        1 + source_buf_len + bit_index_len + name_len))
-}
-
-fn parse_def_create_byte_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let source_buf = parse_term_arg(&data[2..], ctx)?;
+    let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
+    let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
+        source_buf: Box::new(source_buf.val),
+        index: Box::new(bit_index.val),
+        length: Box::new(AmlValue::IntegerConstant(1))
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + source_buf.len + bit_index.len
+    })
+}
+
+fn parse_def_create_byte_field(data: &[u8],
+                               ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x8C);
 
-    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
-    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
-    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
-
-    Ok((NamedObj::DefCreateByteField {name, source_buf, byte_index},
-        1 + source_buf_len + byte_index_len + name_len))
-}
-
-fn parse_def_create_word_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let source_buf = parse_term_arg(&data[2..], ctx)?;
+    let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
+    let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
+        source_buf: Box::new(source_buf.val),
+        index: Box::new(bit_index.val),
+        length: Box::new(AmlValue::IntegerConstant(8))
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + source_buf.len + bit_index.len
+    })
+}
+
+fn parse_def_create_word_field(data: &[u8],
+                               ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x8B);
 
-    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
-    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
-    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
-
-    Ok((NamedObj::DefCreateWordField {name, source_buf, byte_index},
-        1 + source_buf_len + byte_index_len + name_len))
-}
-
-fn parse_def_create_dword_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let source_buf = parse_term_arg(&data[2..], ctx)?;
+    let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
+    let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
+        source_buf: Box::new(source_buf.val),
+        index: Box::new(bit_index.val),
+        length: Box::new(AmlValue::IntegerConstant(16))
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + source_buf.len + bit_index.len
+    })
+}
+
+fn parse_def_create_dword_field(data: &[u8],
+                                ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x8A);
 
-    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
-    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
-    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
-
-    Ok((NamedObj::DefCreateDWordField {name, source_buf, byte_index},
-        1 + source_buf_len + byte_index_len + name_len))
-}
-
-fn parse_def_create_qword_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let source_buf = parse_term_arg(&data[2..], ctx)?;
+    let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
+    let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
+        source_buf: Box::new(source_buf.val),
+        index: Box::new(bit_index.val),
+        length: Box::new(AmlValue::IntegerConstant(32))
+    }));
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + source_buf.len + bit_index.len
+    })
+}
+
+fn parse_def_create_qword_field(data: &[u8],
+                                ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x8F);
 
-    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
-    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
-    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
-
-    Ok((NamedObj::DefCreateQWordField {name, source_buf, byte_index},
-        1 + source_buf_len + byte_index_len + name_len))
-}
-
-fn parse_def_create_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let source_buf = parse_term_arg(&data[2..], ctx)?;
+    let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
+    let name = parse_name_string(&data[1 + source_buf.len + bit_index.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
+        source_buf: Box::new(source_buf.val),
+        index: Box::new(bit_index.val),
+        length: Box::new(AmlValue::IntegerConstant(64))
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + source_buf.len + bit_index.len
+    })
+}
+
+fn parse_def_create_field(data: &[u8],
+                          ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x13);
 
-    let (source_buf, source_buf_len) = parse_term_arg(&data[2..])?;
-    let (bit_index, bit_index_len) = parse_term_arg(&data[2 + source_buf_len..])?;
-    let (num_bits, num_bits_len) = parse_term_arg(&data[2 + source_buf_len + bit_index_len..])?;
-    let (name, name_len) = parse_name_string(
-        &data[2 + source_buf_len + bit_index_len + num_bits_len..])?;
-
-    Ok((NamedObj::DefCreateField {name, source_buf, bit_index, num_bits},
-        2 + source_buf_len + bit_index_len + num_bits_len + name_len))
-}
-
-fn parse_def_data_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let source_buf = parse_term_arg(&data[2..], ctx)?;
+    let bit_index = parse_term_arg(&data[2 + source_buf.len..], ctx)?;
+    let num_bits = parse_term_arg(&data[2 + source_buf.len + bit_index.len..], ctx)?;
+    let name = parse_name_string(&data[2 + source_buf.len + bit_index.len + num_bits.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::BufferField(BufferField {
+        source_buf: Box::new(source_buf.val),
+        index: Box::new(bit_index.val),
+        length: Box::new(num_bits.val)
+    }))?;
+    
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + source_buf.len + bit_index.len + num_bits.len
+    })
+}
+
+fn parse_def_data_region(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: Find the actual offset and length, once table mapping is implemented
     parser_opcode_extended!(data, 0x88);
 
-    let (name, name_len) = parse_name_string(&data[2..])?;
-    let (signature, signature_len) = parse_term_arg(&data[2 + name_len..])?;
-    let (oem_id, oem_id_len) = parse_term_arg(&data[2 + name_len + signature_len..])?;
-    let (oem_table_id, oem_table_id_len) = parse_term_arg(
-        &data[2 + name_len + signature_len + oem_id_len..])?;
+    let name = parse_name_string(&data[2..], ctx)?;
+    let signature = parse_term_arg(&data[2 + name.len..], ctx)?;
+    let oem_id = parse_term_arg(&data[2 + name.len + signature.len..], ctx)?;
+    let oem_table_id = parse_term_arg(&data[2 + name.len + signature.len + oem_id.len..], ctx)?;
 
-    Ok((NamedObj::DefDataRegion {name, signature, oem_id, oem_table_id},
-        2 + name_len + signature_len + oem_id_len + oem_table_id_len))
-}
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
 
-fn parse_def_event(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    ctx.add_to_namespace(local_scope_string, AmlValue::OperationRegion(OperationRegion {
+        region: RegionSpace::SystemMemory,
+        offset: Box::new(AmlValue::IntegerConstant(0)),
+        len: Box::new(AmlValue::IntegerConstant(0)),
+        accessor: Accessor {
+            read: |x| 0 as u64,
+            write: |x, y| ()
+        },
+        accessed_by: None
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len + signature.len + oem_id.len + oem_table_id.len
+    })
+}
+
+fn parse_def_event(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x02);
 
-    let (name, name_len) = parse_name_string(&data[2..])?;
-
-    Ok((NamedObj::DefEvent {name}, 2 + name_len))
-}
-
-fn parse_def_device(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let name = parse_name_string(&data[2..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    ctx.add_to_namespace(local_scope_string, AmlValue::Event(0))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + name.len
+    })
+}
+
+fn parse_def_device(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: How to handle local context deferreds
     parser_opcode_extended!(data, 0x82);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
-    let (name, name_len) = match parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-
-    let obj_list = match parse_object_list(&data[2 + pkg_length_len + name_len .. 2 + pkg_length]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-
-    Ok((NamedObj::DefDevice {name, obj_list}, 2 + pkg_length_len))
-}
-
-fn parse_def_op_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
+    
+    parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?;
+
+    ctx.add_to_namespace(local_scope_string, AmlValue::Device(Device {
+        obj_list: local_ctx.namespace_delta.clone(),
+        notify_methods: BTreeMap::new()
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_length
+    })
+}
+
+fn parse_def_op_region(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x80);
 
-    let (name, name_len) = parse_name_string(&data[2..])?;
-    let region = match data[2 + name_len] {
+    let name = parse_name_string(&data[2..], ctx)?;
+    let region = match data[2 + name.len] {
         0x00 => RegionSpace::SystemMemory,
         0x01 => RegionSpace::SystemIO,
         0x02 => RegionSpace::PCIConfig,
@@ -452,158 +465,241 @@ fn parse_def_op_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalErro
         0x07 => RegionSpace::IPMI,
         0x08 => RegionSpace::GeneralPurposeIO,
         0x09 => RegionSpace::GenericSerialBus,
-        0x80 ... 0xFF => RegionSpace::UserDefined(data[2 + name_len]),
-        _ => return Err(AmlInternalError::AmlParseError("OpRegion - invalid region"))
+        0x80 ... 0xFF => RegionSpace::UserDefined(data[2 + name.len]),
+        _ => return Err(AmlError::AmlParseError("OpRegion - invalid region"))
     };
 
-    let (offset, offset_len) = parse_term_arg(&data[3 + name_len..])?;
-    let (len, len_len) = parse_term_arg(&data[3 + name_len + offset_len..])?;
-
-    Ok((NamedObj::DefOpRegion {name, region, offset, len}, 3 + name_len + offset_len + len_len))
-}
-
-fn parse_def_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let offset = parse_term_arg(&data[3 + name.len..], ctx)?;
+    let len = parse_term_arg(&data[3 + name.len + offset.len..], ctx)?;
+
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    ctx.add_to_namespace(local_scope_string, AmlValue::OperationRegion(OperationRegion {
+        region: region,
+        offset: Box::new(offset.val),
+        len: Box::new(len.val),
+        accessor: Accessor {
+            read: |x| 0 as u64,
+            write: |x, y| ()
+        },
+        accessed_by: None
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 3 + name.len + offset.len + len.len
+    })
+}
+
+fn parse_def_field(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x81);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
-    let (name, name_len) = match parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length])  {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
+    let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
 
-    let flags_raw = data[2 + pkg_length_len + name_len];
-    let flags = FieldFlags {
+    let flags_raw = data[2 + pkg_length_len + name.len];
+    let mut flags = FieldFlags {
         access_type: match flags_raw & 0x0F {
             0 => AccessType::AnyAcc,
             1 => AccessType::ByteAcc,
             2 => AccessType::WordAcc,
             3 => AccessType::DWordAcc,
             4 => AccessType::QWordAcc,
-            5 => AccessType::BufferAcc,
-            _ => return Err(AmlInternalError::AmlParseError("Field - Invalid access type"))
+            5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
+            _ => return Err(AmlError::AmlParseError("Field - Invalid access type"))
         },
         lock_rule: (flags_raw & 0x10) == 0x10,
         update_rule: match (flags_raw & 0x60) >> 5 {
             0 => UpdateRule::Preserve,
             1 => UpdateRule::WriteAsOnes,
             2 => UpdateRule::WriteAsZeros,
-            _ => return Err(AmlInternalError::AmlParseError("Field - Invalid update rule"))
+            _ => return Err(AmlError::AmlParseError("Field - Invalid update rule"))
         }
     };
 
-    let field_list = match parse_field_list(&data[3 + pkg_length_len + name_len .. 2 + pkg_length]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
+    let selector = FieldSelector::Region(name.val.get_as_string()?);
 
-    Ok((NamedObj::DefField {name, flags, field_list}, 2 + pkg_length))
+    parse_field_list(&data[3 + pkg_length_len + name.len .. 2 + pkg_length], ctx, selector, &mut flags)?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_length
+    })
 }
 
-fn parse_def_index_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+fn parse_def_index_field(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x86);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
-    let (idx_name, idx_name_len) = match parse_name_string(
-        &data[2 + pkg_length_len .. 2 + pkg_length])  {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-
-    let (data_name, data_name_len) = match parse_name_string(
-        &data[2 + pkg_length_len + idx_name_len .. 2 + pkg_length])  {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
-    };
+    let idx_name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
+    let data_name = parse_name_string(&data[2 + pkg_length_len + idx_name.len .. 2 + pkg_length], ctx)?;
 
-    let flags_raw = data[2 + pkg_length_len + idx_name_len + data_name_len];
-    let flags = FieldFlags {
+    let flags_raw = data[2 + pkg_length_len + idx_name.len + data_name.len];
+    let mut flags = FieldFlags {
         access_type: match flags_raw & 0x0F {
             0 => AccessType::AnyAcc,
             1 => AccessType::ByteAcc,
             2 => AccessType::WordAcc,
             3 => AccessType::DWordAcc,
             4 => AccessType::QWordAcc,
-            5 => AccessType::BufferAcc,
-            _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid access type"))
+            5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
+            _ => return Err(AmlError::AmlParseError("IndexField - Invalid access type"))
         },
         lock_rule: (flags_raw & 0x10) == 0x10,
         update_rule: match (flags_raw & 0x60) >> 5 {
             0 => UpdateRule::Preserve,
             1 => UpdateRule::WriteAsOnes,
             2 => UpdateRule::WriteAsZeros,
-            _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid update rule"))
+            _ => return Err(AmlError::AmlParseError("IndexField - Invalid update rule"))
         }
     };
 
-    let field_list = match parse_field_list(
-        &data[3 + pkg_length_len + idx_name_len + data_name_len .. 2 + pkg_length]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
-        Err(e) => return Err(e)
+    let selector = FieldSelector::Index {
+        index_selector: idx_name.val.get_as_string()?,
+        data_selector: data_name.val.get_as_string()?
     };
 
-    Ok((NamedObj::DefIndexField {idx_name, data_name, flags, field_list}, 2 + pkg_length))
-}
-
-fn parse_field_list(data: &[u8]) -> Result<Vec<FieldElement>, AmlInternalError> {
-    let mut terms: Vec<FieldElement> = vec!();
+    parse_field_list(&data[3 + pkg_length_len + idx_name.len + data_name.len .. 2 + pkg_length],
+                     ctx, selector, &mut flags)?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_length
+    })
+}
+
+fn parse_field_list(data: &[u8],
+                    ctx: &mut AmlExecutionContext,
+                    selector: FieldSelector,
+                    flags: &mut FieldFlags) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     let mut current_offset: usize = 0;
+    let mut field_offset: usize = 0;
+    let mut connection = AmlValue::Uninitialized;
 
     while current_offset < data.len() {
-        let (res, len) = match parse_field_element(&data[current_offset..]) {
-            Ok(r) => r,
-            Err(AmlInternalError::AmlInvalidOpCode) =>
-                return Err(AmlInternalError::AmlParseError("FieldList - no valid field")),
-            Err(e) => return Err(e)
-        };
-
-        terms.push(res);
-        current_offset += len;
+        let res = parse_field_element(&data[current_offset..], ctx, selector.clone(), &mut connection, flags, &mut field_offset)?;
+        
+        match ctx.state {
+            ExecutionState::EXECUTING => (),
+            _ => return Ok(AmlParseType {
+                val: AmlValue::None,
+                len: 0 as usize
+            })
+        }
+    
+        current_offset += res.len;
     }
 
-    Ok(terms)
-}
-
-fn parse_field_element(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
-    parser_selector! {
-        data,
-        parse_named_field,
-        parse_reserved_field,
-        parse_access_field,
-        parse_connect_field
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: data.len()
+    })
+}
+
+fn parse_field_element(data: &[u8],
+                       ctx: &mut AmlExecutionContext,
+                       selector: FieldSelector,
+                       connection: &mut AmlValue,
+                       flags: &mut FieldFlags,
+                       offset: &mut usize) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    let length = if let Ok(field) = parse_named_field(data, ctx) {
+        let local_scope_string = get_namespace_string(ctx.scope.clone(), AmlValue::String(field.val.name.clone()))?;
+        
+        ctx.add_to_namespace(local_scope_string, AmlValue::FieldUnit(FieldUnit {
+            selector: selector.clone(),
+            connection: Box::new(connection.clone()),
+            flags: flags.clone(),
+            offset: offset.clone(),
+            length: field.val.length
+        }))?;
+
+        *offset += field.val.length;
+        field.len
+    } else if let Ok(field) = parse_reserved_field(data, ctx) {
+        *offset += field.val;
+        field.len
+    } else if let Ok(field) = parse_access_field(data, ctx) {
+        match field.val.access_type {
+            AccessType::BufferAcc(_) =>
+                flags.access_type = AccessType::BufferAcc(field.val.access_attrib.clone()),
+            ref a => flags.access_type = a.clone()
+        }
+        
+        field.len
+    } else if let Ok(field) = parse_connect_field(data, ctx) {
+        *connection = field.val.clone();
+        field.len
+    } else {
+        return Err(AmlError::AmlInvalidOpCode);
     };
-
-    Err(AmlInternalError::AmlInvalidOpCode)
+    
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: length
+    })
 }
 
-fn parse_named_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+fn parse_named_field(data: &[u8],
+                     ctx: &mut AmlExecutionContext) -> Result<AmlParseTypeGeneric<NamedField>, AmlError> {
     let (name_seg, name_seg_len) = parse_name_seg(&data[0..4])?;
     let name = match String::from_utf8(name_seg) {
         Ok(s) => s,
-        Err(_) => return Err(AmlInternalError::AmlParseError("NamedField - invalid name"))
+        Err(_) => return Err(AmlError::AmlParseError("NamedField - invalid name"))
     };
     let (length, length_len) = parse_pkg_length(&data[4..])?;
 
-    Ok((FieldElement::NamedField {name, length}, 4 + length_len))
+    Ok(AmlParseTypeGeneric {
+        val: NamedField { name, length },
+        len: name_seg_len + length_len
+    })
 }
 
-fn parse_reserved_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+fn parse_reserved_field(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> Result<AmlParseTypeGeneric<usize>, AmlError> {
     parser_opcode!(data, 0x00);
 
     let (length, length_len) = parse_pkg_length(&data[1..])?;
-    Ok((FieldElement::ReservedField {length}, 1 + length_len))
+    Ok(AmlParseTypeGeneric {
+        val: length,
+        len: 1 + length_len
+    })
 }
 
-fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+fn parse_access_field(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> Result<AmlParseTypeGeneric<AccessField>, AmlError> {
     parser_opcode!(data, 0x01, 0x03);
 
     let flags_raw = data[1];
@@ -613,8 +709,8 @@ fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalE
         2 => AccessType::WordAcc,
         3 => AccessType::DWordAcc,
         4 => AccessType::QWordAcc,
-        5 => AccessType::BufferAcc,
-        _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access type"))
+        5 => AccessType::BufferAcc(AccessAttrib::AttribByte),
+        _ => return Err(AmlError::AmlParseError("AccessField - Invalid access type"))
     };
 
     let access_attrib = match (flags_raw & 0xC0) >> 6 {
@@ -629,155 +725,252 @@ fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalE
             0x0D => AccessAttrib::AttribBlockProcessCall,
             0x0E => AccessAttrib::AttribRawBytes(data[3]),
             0x0F => AccessAttrib::AttribRawProcessBytes(data[3]),
-            _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access attrib"))
+            _ => return Err(AmlError::AmlParseError("AccessField - Invalid access attrib"))
         },
         1 => AccessAttrib::AttribBytes(data[2]),
         2 => AccessAttrib::AttribRawBytes(data[2]),
         3 => AccessAttrib::AttribRawProcessBytes(data[2]),
-        _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access attrib"))
+        _ => return Err(AmlError::AmlParseError("AccessField - Invalid access attrib"))
             // This should never happen but the compiler bitches if I don't cover this
     };
 
-    return Ok((FieldElement::AccessField {access_type, access_attrib}, if data[0] == 0x01 {
-        3 as usize
-    } else {
-        4 as usize
-    }))
+    Ok(AmlParseTypeGeneric {
+        val: AccessField { access_type, access_attrib },
+        len: if data[0] == 0x01 {
+            3 as usize
+        } else {
+            4 as usize
+        }
+    })
 }
 
-fn parse_connect_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
-    parser_opcode!(data, 0x02);
-
-    match parse_def_buffer(&data[1..]) {
-        Ok((buf, buf_len)) => return Ok((FieldElement::ConnectFieldBufferData(buf), buf_len + 1)),
-        Err(AmlInternalError::AmlInvalidOpCode) => (),
-        Err(e) => return Err(e)
+fn parse_connect_field(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x02);
 
-    match parse_name_string(&data[1..]) {
-        Ok((name, name_len)) => Ok((FieldElement::ConnectFieldNameString(name), name_len + 1)),
-        Err(AmlInternalError::AmlInvalidOpCode) => Err(AmlInternalError::AmlParseError("ConnectField - unable to match field")),
-        Err(e) => Err(e)
+    if let Ok(e) = parse_def_buffer(&data[1..], ctx) {
+        Ok(AmlParseType {
+            val: e.val,
+            len: e.len + 1
+        })
+    } else {
+        let name = parse_name_string(&data[1..], ctx)?;
+        Ok(AmlParseType {
+            val: AmlValue::Alias(name.val.get_as_string()?),
+            len: name.len + 1
+        })
     }
 }
 
-fn parse_def_method(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+fn parse_def_method(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x14);
 
     let (pkg_len, pkg_len_len) = parse_pkg_length(&data[1..])?;
-    let (name, name_len) = match parse_name_string(&data[1 + pkg_len_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 1 + pkg_len].to_vec()), 1 + pkg_len)),
-        Err(e) => return Err(e)
-    };
-    let flags = data[1 + pkg_len_len + name_len];
+    let name = parse_name_string(&data[1 + pkg_len_len..], ctx)?;
+    let flags = data[1 + pkg_len_len + name.len];
 
     let arg_count = flags & 0x07;
     let serialized = (flags & 0x08) == 0x08;
     let sync_level = flags & 0xF0 >> 4;
 
-    let term_list = match parse_term_list(&data[2 + pkg_len_len + name_len .. 1 + pkg_len]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 1 + pkg_len].to_vec()), 1 + pkg_len)),
-        Err(e) => return Err(e)
-    };
-
-    Ok((NamedObj::DefMethod {
-        name: name,
-        method: Method {
-            arg_count,
-            serialized,
-            sync_level,
-            term_list
-        }
-    }, pkg_len + 1))
-}
-
-fn parse_def_mutex(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let term_list = &data[2 + pkg_len_len + name.len .. 1 + pkg_len];
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    ctx.add_to_namespace(local_scope_string, AmlValue::Method(Method {
+        arg_count,
+        serialized,
+        sync_level,
+        term_list: term_list.to_vec()
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + pkg_len
+    })
+}
+
+fn parse_def_mutex(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x01);
 
-    let (name, name_len) = match parse_name_string(&data[2 ..]) {
-        Ok(p) => p,
-        Err(e) => return Err(e),
-    };
-    let flags = data[2 + name_len];
+    let name = parse_name_string(&data[2 ..], ctx)?;
+    let flags = data[2 + name.len];
     let sync_level = flags & 0x0F;
-
-    Ok((NamedObj::DefMutex {name, sync_level}, name_len + 3))
-}
-
-fn parse_def_power_res(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    ctx.add_to_namespace(local_scope_string, AmlValue::Mutex((sync_level, None)))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 3 + name.len
+    })
+}
+
+fn parse_def_power_res(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: How to handle local context deferreds
     parser_opcode_extended!(data, 0x84);
 
     let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
-    let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
-        Err(e) => return Err(e)
-    };
-
-    let system_level = data[2 + pkg_len_len + name_len];
-    let resource_order: u16 = (data[3 + pkg_len_len + name_len] as u16) +
-        ((data[4 + pkg_len_len + name_len] as u16) << 8);
-
-    let obj_list = match parse_object_list(&data[5 + pkg_len_len + name_len .. 2 + pkg_len]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
-        Err(e) => return Err(e)
-    };
-
-    Ok((NamedObj::DefPowerRes {name, system_level, resource_order, obj_list}, 2 + pkg_len))
-}
-
-fn parse_def_processor(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    let name = parse_name_string(&data[2 + pkg_len_len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+
+    let system_level = data[2 + pkg_len_len + name.len];
+    let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) +
+        ((data[4 + pkg_len_len + name.len] as u16) << 8);
+
+    let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
+    parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::PowerResource(PowerResource {
+        system_level,
+        resource_order,
+        obj_list: local_ctx.namespace_delta.clone()
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_len
+    })
+}
+
+fn parse_def_processor(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x83);
 
     let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
-    let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
-        Err(e) => return Err(e)
-    };
-
-    let proc_id = data[2 + pkg_len_len + name_len];
-    let p_blk_addr: u32 = (data[3 + pkg_len_len + name_len] as u32) +
-        ((data[4 + pkg_len_len + name_len] as u32) << 8) +
-        ((data[5 + pkg_len_len + name_len] as u32) << 16) +
-        ((data[6 + pkg_len_len + name_len] as u32) << 24);
-    let p_blk_len = data[7 + pkg_len_len + name_len];
-
-    let obj_list = match parse_object_list(&data[8 + pkg_len_len + name_len .. 2 + pkg_len]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
-        Err(e) => return Err(e)
-    };
-
-    Ok((NamedObj::DefProcessor {name, proc_id, p_blk_addr, p_blk_len, obj_list}, 2 + pkg_len))
-}
-
-fn parse_def_thermal_zone(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
-    parser_opcode_extended!(data, 0x85);
-
+    let name = parse_name_string(&data[2 + pkg_len_len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+    
+    let proc_id = data[2 + pkg_len_len + name.len];
+    let p_blk_addr: u32 = (data[3 + pkg_len_len + name.len] as u32) +
+        ((data[4 + pkg_len_len + name.len] as u32) << 8) +
+        ((data[5 + pkg_len_len + name.len] as u32) << 16) +
+        ((data[6 + pkg_len_len + name.len] as u32) << 24);
+    let p_blk_len = data[7 + pkg_len_len + name.len];
+
+    let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
+    parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
+
+    ctx.add_to_namespace(local_scope_string, AmlValue::Processor(Processor {
+        proc_id: proc_id,
+        p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None },
+        obj_list: local_ctx.namespace_delta.clone(),
+        notify_methods: BTreeMap::new()
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_len
+    })
+}
+
+fn parse_def_thermal_zone(data: &[u8],
+                          ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x85);    
+    
     let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
-    let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
-        Err(e) => return Err(e)
+    let name = parse_name_string(&data[2 + pkg_len_len .. 2 + pkg_len], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+
+    let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());    
+    parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
+    
+    ctx.add_to_namespace(local_scope_string, AmlValue::ThermalZone(ThermalZone {
+        obj_list: local_ctx.namespace_delta.clone(),
+        notify_methods: BTreeMap::new()
+    }))?;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + pkg_len
+    })
+}
+
+fn parse_def_external(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x15);
+
+    let object_name = parse_name_string(&data[1..], ctx)?;
+    let object_type = data[1 + object_name.len];
+    let argument_count = data[2 + object_name.len];
+
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), object_name.val)?;
+
+    let obj = match object_type {
+        8 => AmlValue::Method(Method {
+            arg_count: argument_count,
+            serialized: false,
+            sync_level: 0,
+            term_list: vec!()
+        }),
+        _ => AmlValue::Uninitialized
     };
 
-    let obj_list = match parse_object_list(&data[2 + pkg_len_len + name_len .. 2 + pkg_len]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
-        Err(e) => return Err(e)
-    };
+    ctx.add_to_namespace(local_scope_string, obj)?;
 
-    Ok((NamedObj::DefThermalZone {name, obj_list}, 2 + pkg_len))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 3 + object_name.len
+    })
 }
diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs
index dc3c1c89733e2ce64018f70710744493a825c198..18eb7a34e49bd5362ff55d1c8a1a5ff4cb0d3ced 100644
--- a/src/acpi/aml/namespace.rs
+++ b/src/acpi/aml/namespace.rs
@@ -1,225 +1,491 @@
 use alloc::boxed::Box;
 use collections::string::String;
+use collections::string::ToString;
 use collections::vec::Vec;
+use collections::btree_map::BTreeMap;
 
+use core::fmt::{Debug, Formatter, Error};
 use core::str::FromStr;
 
-use super::namedobj::{ RegionSpace, FieldFlags, Method };
+use super::termlist::parse_term_list;
+use super::namedobj::{ RegionSpace, FieldFlags };
+use super::parser::{AmlExecutionContext, ExecutionState};
+use super::AmlError;
 
-#[derive(Debug, Clone)]
-pub struct AmlNamespace {
-    name: String,
-    contents: AmlNamespaceContents
-}
+use acpi::{SdtSignature, get_signature_from_index, get_index_from_signature};
 
-#[derive(Debug, Clone)]
-pub enum AmlNamespaceContents {
-    Value(AmlValue),
-    SubNamespace(Box<AmlNamespace>),
-    Namespace(Vec<AmlNamespaceContents>),
-    OpRegion {
-        region: RegionSpace,
-        offset: AmlValue,
-        len: AmlValue
+#[derive(Clone)]
+pub enum FieldSelector {
+    Region(String),
+    Bank {
+        region: String,
+        bank_register: String,
+        bank_selector: Box<AmlValue>
     },
-    Field {
-        op_region: String,
-        flags: FieldFlags,
-        offset: usize,
-        length: usize
+    Index {
+        index_selector: String,
+        data_selector: String
+    }
+}
+
+#[derive(Clone)]
+pub enum ObjectReference {
+    ArgObj(u8),
+    LocalObj(u8),
+    Object(String),
+    Index(Box<AmlValue>, Box<AmlValue>)
+}
+
+#[derive(Clone)]
+pub struct Method {
+    pub arg_count: u8,
+    pub serialized: bool,
+    pub sync_level: u8,
+    pub term_list: Vec<u8>
+}
+
+#[derive(Clone)]
+pub struct BufferField {
+    pub source_buf: Box<AmlValue>,
+    pub index: Box<AmlValue>,
+    pub length: Box<AmlValue>
+}
+
+#[derive(Clone)]
+pub struct FieldUnit {
+    pub selector: FieldSelector,
+    pub connection: Box<AmlValue>,
+    pub flags: FieldFlags,
+    pub offset: usize,
+    pub length: usize
+}
+
+#[derive(Clone)]
+pub struct Device {
+    pub obj_list: Vec<String>,
+    pub notify_methods: BTreeMap<u8, Vec<fn()>>
+}
+
+#[derive(Clone)]
+pub struct ThermalZone {
+    pub obj_list: Vec<String>,
+    pub notify_methods: BTreeMap<u8, Vec<fn()>>
+}
+
+#[derive(Clone)]
+pub struct Processor {
+    pub proc_id: u8,
+    pub p_blk: Option<u32>,
+    pub obj_list: Vec<String>,
+    pub notify_methods: BTreeMap<u8, Vec<fn()>>
+}
+
+#[derive(Clone)]
+pub struct OperationRegion {
+    pub region: RegionSpace,
+    pub offset: Box<AmlValue>,
+    pub len: Box<AmlValue>,
+    pub accessor: Accessor,
+    pub accessed_by: Option<u64>
+}
+
+#[derive(Clone)]
+pub struct PowerResource {
+    pub system_level: u8,
+    pub resource_order: u16,
+    pub obj_list: Vec<String>
+}
+
+pub struct Accessor {
+    pub read: fn(usize) -> u64,
+    pub write: fn(usize, u64)
+}
+
+impl Clone for Accessor {
+    fn clone(&self) -> Accessor {
+        Accessor {
+            read: (*self).read,
+            write: (*self).write
+        }
     }
 }
 
-#[derive(Debug, Clone)]
+#[derive(Clone)]
 pub enum AmlValue {
+    None,
     Uninitialized,
-    Buffer,
-    BufferField,
-    DDBHandle,
+    Alias(String),
+    Buffer(Vec<u8>),
+    BufferField(BufferField),
+    DDBHandle((Vec<String>, SdtSignature)),
     DebugObject,
-    Device,
-    Event,
-    FieldUnit,
-    Integer,
+    Device(Device),
+    Event(u64),
+    FieldUnit(FieldUnit),
+    Integer(u64),
     IntegerConstant(u64),
     Method(Method),
-    Mutex,
-    ObjectReference,
-    OperationRegion,
+    Mutex((u8, Option<u64>)),
+    ObjectReference(ObjectReference),
+    OperationRegion(OperationRegion),
     Package(Vec<AmlValue>),
-    String,
-    PowerResource,
-    Processor,
-    RawDataBuffer,
-    ThermalZone
+    String(String),
+    PowerResource(PowerResource),
+    Processor(Processor),
+    RawDataBuffer(Vec<u8>),
+    ThermalZone(ThermalZone)
+}
+
+impl Debug for AmlValue {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { Ok(()) }
 }
 
 impl AmlValue {
-    pub fn get_as_package(&self) -> Option<Vec<AmlValue>> {
+    pub fn get_type_string(&self) -> String {
         match *self {
-            AmlValue::Package(ref p) => Some(p.clone()),
-            _ => None
+            AmlValue::Uninitialized => String::from_str("[Uninitialized Object]").unwrap(),
+            AmlValue::Integer(_) => String::from_str("[Integer]").unwrap(),
+            AmlValue::String(_) => String::from_str("[String]").unwrap(),
+            AmlValue::Buffer(_) => String::from_str("[Buffer]").unwrap(),
+            AmlValue::Package(_) => String::from_str("[Package]").unwrap(),
+            AmlValue::FieldUnit(_) => String::from_str("[Field]").unwrap(),
+            AmlValue::Device(_) => String::from_str("[Device]").unwrap(),
+            AmlValue::Event(_) => String::from_str("[Event]").unwrap(),
+            AmlValue::Method(_) => String::from_str("[Control Method]").unwrap(),
+            AmlValue::Mutex(_) => String::from_str("[Mutex]").unwrap(),
+            AmlValue::OperationRegion(_) => String::from_str("[Operation Region]").unwrap(),
+            AmlValue::PowerResource(_) => String::from_str("[Power Resource]").unwrap(),
+            AmlValue::Processor(_) => String::from_str("[Processor]").unwrap(),
+            AmlValue::ThermalZone(_) => String::from_str("[Thermal Zone]").unwrap(),
+            AmlValue::BufferField(_) => String::from_str("[Buffer Field]").unwrap(),
+            AmlValue::DDBHandle(_) => String::from_str("[DDB Handle]").unwrap(),
+            AmlValue::DebugObject => String::from_str("[Debug Object]").unwrap(),
+            _ => String::new()
+        }
+    }
+    
+    pub fn get_as_type(&self, t: AmlValue) -> Result<AmlValue, AmlError> {
+        match t {
+            AmlValue::None => Ok(AmlValue::None),
+            AmlValue::Uninitialized => Ok(self.clone()),
+            AmlValue::Alias(_) => match *self {
+                AmlValue::Alias(_) => Ok(self.clone()),
+                _ => Err(AmlError::AmlValueError)
+            },
+            AmlValue::Buffer(_) => Ok(AmlValue::Buffer(self.get_as_buffer()?)),
+            AmlValue::BufferField(_) => Ok(AmlValue::BufferField(self.get_as_buffer_field()?)),
+            AmlValue::DDBHandle(_) => Ok(AmlValue::DDBHandle(self.get_as_ddb_handle()?)),
+            AmlValue::DebugObject => match *self {
+                AmlValue::DebugObject => Ok(self.clone()),
+                _ => Err(AmlError::AmlValueError)
+            },
+            AmlValue::Device(_) => Ok(AmlValue::Device(self.get_as_device()?)),
+            AmlValue::Event(_) => Ok(AmlValue::Event(self.get_as_event()?)),
+            AmlValue::FieldUnit(_) => Ok(AmlValue::FieldUnit(self.get_as_field_unit()?)),
+            AmlValue::Integer(_) => Ok(AmlValue::Integer(self.get_as_integer()?)),
+            AmlValue::IntegerConstant(_) => Ok(AmlValue::IntegerConstant(self.get_as_integer_constant()?)),
+            AmlValue::Method(_) => Ok(AmlValue::Method(self.get_as_method()?)),
+            AmlValue::Mutex(_) => Ok(AmlValue::Mutex(self.get_as_mutex()?)),
+            AmlValue::ObjectReference(_) => Ok(AmlValue::ObjectReference(self.get_as_object_reference()?)),
+            AmlValue::OperationRegion(_) => match *self {
+                AmlValue::OperationRegion(_) => Ok(self.clone()),
+                _ => Err(AmlError::AmlValueError)
+            },
+            AmlValue::Package(_) => Ok(AmlValue::Package(self.get_as_package()?)),
+            AmlValue::String(_) => Ok(AmlValue::String(self.get_as_string()?)),
+            AmlValue::PowerResource(_) => Ok(AmlValue::PowerResource(self.get_as_power_resource()?)),
+            AmlValue::Processor(_) => Ok(AmlValue::Processor(self.get_as_processor()?)),
+            AmlValue::RawDataBuffer(_) => Ok(AmlValue::RawDataBuffer(self.get_as_raw_data_buffer()?)),
+            AmlValue::ThermalZone(_) => Ok(AmlValue::ThermalZone(self.get_as_thermal_zone()?))
         }
     }
 
-    pub fn get_as_integer(&self) -> Option<u64> {
+    pub fn get_as_buffer(&self) -> Result<Vec<u8>, AmlError> {
         match *self {
-            AmlValue::IntegerConstant(ref i) => Some(i.clone()),
-            _ => None
+            AmlValue::Buffer(ref b) => Ok(b.clone()),
+            AmlValue::Integer(ref i) => {
+                let mut v: Vec<u8> = vec!();
+                let mut i = i.clone();
+
+                while i != 0 {
+                    v.push((i & 0xFF) as u8);
+                    i >>= 8;
+                }
+
+                while v.len() < 8 {
+                    v.push(0);
+                }
+
+                Ok(v)
+            },
+            AmlValue::String(ref s) => {
+                Ok(s.clone().into_bytes())
+            },
+            AmlValue::BufferField(ref b) => {
+                let buf = b.source_buf.get_as_buffer()?;
+                let idx = b.index.get_as_integer()? as usize;
+                let len = b.length.get_as_integer()? as usize;
+
+                if idx + len > buf.len() {
+                    return Err(AmlError::AmlValueError);
+                }
+                
+                Ok(buf[idx .. idx + len].to_vec())
+            },
+            _ => Err(AmlError::AmlValueError)
         }
     }
-}
 
-impl AmlNamespace {
-    pub fn new_namespace(name: &String) -> AmlNamespace {
-        AmlNamespace {
-            name: name.clone(),
-            contents: AmlNamespaceContents::Namespace(vec!())
+    pub fn get_as_buffer_field(&self) -> Result<BufferField, AmlError> {
+        match *self {
+            AmlValue::BufferField(ref b) => Ok(b.clone()),
+            _ => {
+                let raw_buf = self.get_as_buffer()?;
+                let buf = Box::new(AmlValue::Buffer(raw_buf.clone()));
+                let idx = Box::new(AmlValue::IntegerConstant(0));
+                let len = Box::new(AmlValue::Integer(raw_buf.len() as u64));
+
+                Ok(BufferField {
+                    source_buf: buf,
+                    index: idx,
+                    length: len
+                })
+            }
         }
     }
 
-    pub fn find_str(&self, scope_str: &str) -> Option<AmlValue> {
-        let scope_string = String::from_str(scope_str).unwrap();
-        self.find(scope_string)
+    pub fn get_as_ddb_handle(&self) -> Result<(Vec<String>, SdtSignature), AmlError> {
+        match *self {
+            AmlValue::DDBHandle(ref v) => Ok(v.clone()),
+            AmlValue::Integer(i) => if let Some(sig) = get_signature_from_index(i as usize) {
+                Ok((vec!(), sig))
+            } else {
+                Err(AmlError::AmlValueError)
+            },
+            _ => Err(AmlError::AmlValueError)
+        }
     }
 
-    pub fn find(&self, scope_string: String) -> Option<AmlValue> {
-        if scope_string.len() == 0 {
-            match self.contents {
-                AmlNamespaceContents::Value(ref v) => return Some(v.clone()),
-                _ => return None
-            }
+    pub fn get_as_device(&self) -> Result<Device, AmlError> {
+        match *self {
+            AmlValue::Device(ref s) => Ok(s.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_event(&self) -> Result<u64, AmlError> {
+        match *self {
+            AmlValue::Event(ref e) => Ok(e.clone()),
+            _ => Err(AmlError::AmlValueError)
         }
+    }
+    
+    pub fn get_as_field_unit(&self) -> Result<FieldUnit, AmlError> {
+        match *self {
+            AmlValue::FieldUnit(ref e) => Ok(e.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
 
-        let mut scope_string = scope_string.clone();
+    pub fn get_as_integer(&self) -> Result<u64, AmlError> {
+        match *self {
+            AmlValue::IntegerConstant(ref i) => Ok(i.clone()),
+            AmlValue::Integer(ref i) => Ok(i.clone()),
+            AmlValue::Buffer(ref b) => {
+                let mut b = b.clone();
+                if b.len() > 8 {
+                    return Err(AmlError::AmlValueError);
+                }
 
-        if scope_string.starts_with("\\") {
-            if self.name != "\\" {
-                return None;
-            }
+                let mut i: u64 = 0;
 
-            scope_string.remove(0);
-        }
+                while b.len() > 0 {
+                    i <<= 8;
+                    i += b.pop().expect("Won't happen") as u64;
+                }
 
-        if scope_string.starts_with(".") {
-            scope_string.remove(0);
-        }
+                Ok(i)
+            },
+            AmlValue::BufferField(_) => {
+                let mut b = self.get_as_buffer()?;
+                if b.len() > 8 {
+                    return Err(AmlError::AmlValueError);
+                }
 
-        if scope_string.len() == 0 {
-            match self.contents {
-                AmlNamespaceContents::Value(ref v) => return Some(v.clone()),
-                _ => return None
-            }
-        }
+                let mut i: u64 = 0;
 
-        let (current, nextset) = match scope_string.find(".") {
-            Some(s) => {
-                let (x, mut y) = scope_string.split_at(s);
-                y = &y[1..];
+                while b.len() > 0 {
+                    i <<= 8;
+                    i += b.pop().expect("Won't happen") as u64;
+                }
 
-                (String::from_str(x).unwrap(), String::from_str(y).unwrap())
+                Ok(i)
             },
-            None => if scope_string.len() <= 4 {
-                (scope_string, String::from_str("").unwrap())
+            AmlValue::DDBHandle(ref v) => if let Some(idx) = get_index_from_signature(v.1.clone()) {
+                Ok(idx as u64)
             } else {
-                return None;
-            }
-        };
-
-        match self.contents {
-            AmlNamespaceContents::Namespace(ref namespace) => {
-                // TODO: Remove this while loop here, there has to be a more elegant way
-                let mut current_index = 0;
-                while current_index < namespace.len() {
-                    match namespace[current_index] {
-                        AmlNamespaceContents::SubNamespace(ref ns) => if ns.name == current {
-                            return ns.find(nextset);
-                        },
-                        _ => ()
-                    }
+                Err(AmlError::AmlValueError)
+            },
+            AmlValue::String(ref s) => {
+                let mut s = s.clone()[0..8].to_string().to_uppercase();
+                let mut i: u64 = 0;
 
-                    current_index += 1;
+                for c in s.chars() {
+                    if !c.is_digit(16) {
+                        break;
+                    }
+                    
+                    i <<= 8;
+                    i += c.to_digit(16).unwrap() as u64;
                 }
+
+                Ok(i)
             },
-            _ => ()
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+
+    pub fn get_as_integer_constant(&self) -> Result<u64, AmlError> {
+        match *self {
+            AmlValue::IntegerConstant(ref i) => Ok(i.clone()),
+            _ => Err(AmlError::AmlValueError)
         }
+    }
 
-        None
+    pub fn get_as_method(&self) -> Result<Method, AmlError> {
+        match *self {
+            AmlValue::Method(ref m) => Ok(m.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
     }
 
-    pub fn push(&mut self, val: AmlNamespaceContents) {
-        match self.contents {
-            AmlNamespaceContents::Namespace(ref mut v) => v.push(val),
-            _ => () // TODO: Error this
+    pub fn get_as_mutex(&self) -> Result<(u8, Option<u64>), AmlError> {
+        match *self {
+            AmlValue::Mutex(ref m) => Ok(m.clone()),
+            _ => Err(AmlError::AmlValueError)
         }
     }
 
-    pub fn push_to(&mut self, scope_string: String, contents: AmlNamespaceContents) {
-        if scope_string.len() == 0 {
-            return;
+    pub fn get_as_object_reference(&self) -> Result<ObjectReference, AmlError> {
+        match *self {
+            AmlValue::ObjectReference(ref m) => Ok(m.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_operation_region(&self) -> Result<OperationRegion, AmlError> {
+        match *self {
+            AmlValue::OperationRegion(ref p) => Ok(p.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_package(&self) -> Result<Vec<AmlValue>, AmlError> {
+        match *self {
+            AmlValue::Package(ref p) => Ok(p.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_string(&self) -> Result<String, AmlError> {
+        match *self {
+            AmlValue::String(ref s) => Ok(s.clone()),
+            AmlValue::Integer(ref i) => Ok(format!("{:X}", i)),
+            AmlValue::IntegerConstant(ref i) => Ok(format!("{:X}", i)),
+            AmlValue::Buffer(ref b) => Ok(String::from_utf8(b.clone()).expect("Invalid UTF-8")),
+            AmlValue::BufferField(_) => {
+                let b = self.get_as_buffer()?;
+                Ok(String::from_utf8(b).expect("Invalid UTF-8"))
+            },
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_power_resource(&self) -> Result<PowerResource, AmlError> {
+        match *self {
+            AmlValue::PowerResource(ref p) => Ok(p.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_processor(&self) -> Result<Processor, AmlError> {
+        match *self {
+            AmlValue::Processor(ref p) => Ok(p.clone()),
+            _ => Err(AmlError::AmlValueError)
         }
+    }
+    
+    pub fn get_as_raw_data_buffer(&self) -> Result<Vec<u8>, AmlError> {
+        match *self {
+            AmlValue::RawDataBuffer(ref p) => Ok(p.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+    
+    pub fn get_as_thermal_zone(&self) -> Result<ThermalZone, AmlError> {
+        match *self {
+            AmlValue::ThermalZone(ref p) => Ok(p.clone()),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+}
 
-        let mut scope_string = scope_string.clone();
+impl Method {
+    pub fn execute(&self, scope: String, parameters: Vec<AmlValue>) -> AmlValue {
+        let mut ctx = AmlExecutionContext::new(scope);
+        ctx.init_arg_vars(parameters);
 
-        if scope_string.starts_with("\\") {
-            if self.name != "\\" {
-                return;
-                // TODO: Error this
-            }
+        parse_term_list(&self.term_list[..], &mut ctx);
+        ctx.clean_namespace();
 
-            scope_string.remove(0);
+        match ctx.state {
+            ExecutionState::RETURN(v) => v,
+            _ => AmlValue::IntegerConstant(0)
         }
+    }
+}
 
-        if scope_string.starts_with(".") {
-            scope_string.remove(0);
-        }
+pub fn get_namespace_string(current: String, modifier_v: AmlValue) -> Result<String, AmlError> {
+    let mut modifier = modifier_v.get_as_string()?;
+    
+    if current.len() == 0 {
+        return Ok(modifier);
+    }
 
-        if scope_string.len() == 0 {
-            return;
-        }
+    if modifier.len() == 0 {
+        return Ok(current);
+    }
+    
+    if modifier.starts_with("\\") {
+        return Ok(modifier);
+    }
 
-        let (current, nextset) = match scope_string.find(".") {
-            Some(s) => {
-                let (x, mut y) = scope_string.split_at(s);
-                y = &y[1..];
+    let mut namespace = current.clone();
 
-                (String::from_str(x).unwrap(), String::from_str(y).unwrap())
-            },
-            None => if scope_string.len() <= 4 {
-                (scope_string, String::from_str("").unwrap())
-            } else {
-                return;
+    if modifier.starts_with("^") {
+        while modifier.starts_with("^") {
+            modifier = modifier[1..].to_string();
+
+            if namespace.ends_with("\\") {
+                return Err(AmlError::AmlValueError);
             }
-        };
-
-        match self.contents {
-            AmlNamespaceContents::Namespace(ref mut namespace) => {
-                // TODO: Remove this while loop here, there has to be a more elegant way
-                let mut current_index = 0;
-                while current_index < namespace.len() {
-                    match namespace[current_index] {
-                        AmlNamespaceContents::SubNamespace(ref mut ns) => if ns.name == current {
-                            ns.push_to(nextset, contents);
-                            return;
-                        },
-                        _ => ()
-                    }
 
-                    current_index += 1;
+            loop {
+                if namespace.ends_with(".") {
+                    namespace.pop();
+                    break;
                 }
 
-                let mut next = AmlNamespace {
-                    name: current,
-                    contents: contents
-                };
-
-                namespace.push(AmlNamespaceContents::SubNamespace(Box::new(next)));
+                if namespace.pop() == None {
+                    return Err(AmlError::AmlValueError);
+                }
             }
-            _ => () // TODO: Error this
         }
     }
 
-    pub fn push_subordinate_namespace(&mut self, scope_string: String) {
-        self.push_to(scope_string, AmlNamespaceContents::Namespace(vec!()));
+    if !namespace.ends_with("\\") {
+        namespace.push('.');
     }
+    
+    Ok(namespace + &modifier)
 }
diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs
index 217347a0bf2ea82156234ddf4066dc982d990895..a223f5c8ad72bd181819858b8ac756932386bd76 100644
--- a/src/acpi/aml/namespacemodifier.rs
+++ b/src/acpi/aml/namespacemodifier.rs
@@ -1,102 +1,106 @@
-use alloc::boxed::Box;
-use collections::string::String;
-use collections::vec::Vec;
-
-use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, AmlNamespaceContents, get_namespace_string};
+use super::AmlError;
+use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
+use super::namespace::{AmlValue, ObjectReference, get_namespace_string};
 use super::pkglength::parse_pkg_length;
 use super::namestring::parse_name_string;
-use super::termlist::{parse_term_list, TermObj};
-use super::dataobj::{parse_data_ref_obj, DataRefObj};
-
-#[derive(Debug, Clone)]
-pub enum NamespaceModifier {
-    Name {
-        name: String,
-        data_ref_obj: DataRefObj
-    },
-    Scope {
-        name: String,
-        terms: Vec<TermObj>
-    },
-    Alias {
-        source_name: String,
-        alias_name: String
-    },
-    DeferredLoad(Vec<u8>)
-}
-
-impl AmlExecutable for NamespaceModifier {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            NamespaceModifier::Scope { name: ref name, terms: ref terms } => {
-                let local_scope_string = get_namespace_string(scope, name.clone());
-                namespace.push_subordinate_namespace(local_scope_string.clone());
-
-                terms.execute(namespace, local_scope_string);
-            },
-            NamespaceModifier::Name { ref name, ref data_ref_obj } => {
-                let local_scope_string = get_namespace_string(scope.clone(), name.clone());
-                let dro = match data_ref_obj.execute(namespace, scope) {
-                    Some(s) => s,
-                    None => return None
-                };
-
-                namespace.push_to(local_scope_string, AmlNamespaceContents::Value(dro));
-            },
-            _ => ()
-        }
-
-        None
+use super::termlist::parse_term_list;
+use super::dataobj::parse_data_ref_obj;
+
+pub fn parse_namespace_modifier(data: &[u8],
+                                ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
-}
-
-pub fn parse_namespace_modifier(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+    
     parser_selector! {
-        data,
+        data, ctx,
         parse_alias_op,
         parse_scope_op,
         parse_name_op
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-fn parse_alias_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+fn parse_alias_op(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x06);
 
-    let (source_name, source_name_len) = parse_name_string(&data[1..])?;
-    let (alias_name, alias_name_len) = parse_name_string(&data[1 + source_name_len..])?;
-
-    Ok((NamespaceModifier::Alias {source_name, alias_name}, 1 + source_name_len + alias_name_len))
+    let source_name = parse_name_string(&data[1..], ctx)?;
+    let alias_name = parse_name_string(&data[1 + source_name.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), source_name.val)?;
+    let local_alias_string = get_namespace_string(ctx.scope.clone(), alias_name.val)?;
+
+    ctx.add_to_namespace(local_scope_string, AmlValue::Alias(local_alias_string))?;
+    
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + source_name.len + alias_name.len
+    })
 }
 
-fn parse_name_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+fn parse_name_op(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x08);
-
-    let (name, name_len) = parse_name_string(&data[1..])?;
-    let (data_ref_obj, data_ref_obj_len) = parse_data_ref_obj(&data[1 + name_len..])?;
-
-    Ok((NamespaceModifier::Name {name, data_ref_obj}, 1 + name_len + data_ref_obj_len))
+    
+    let name = parse_name_string(&data[1..], ctx)?;
+    let data_ref_obj = parse_data_ref_obj(&data[1 + name.len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val)?;
+
+    ctx.add_to_namespace(local_scope_string, data_ref_obj.val)?;
+    
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + name.len + data_ref_obj.len
+    })
 }
 
-fn parse_scope_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+fn parse_scope_op(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x10);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-    let (name, name_len) = match parse_name_string(&data[1 + pkg_length_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamespaceModifier::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
-                       1 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-    let terms = match parse_term_list(&data[1 + pkg_length_len + name_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((NamespaceModifier::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
-                       1 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-
-    Ok((NamespaceModifier::Scope {name, terms}, pkg_length + 1))
+    let name = parse_name_string(&data[1 + pkg_length_len..], ctx)?;
+    
+    let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val.clone())?;
+    let containing_scope_string = ctx.scope.clone();
+    
+    ctx.scope = local_scope_string;
+    parse_term_list(&data[1 + pkg_length_len + name.len .. 1 + pkg_length], ctx)?;
+    ctx.scope = containing_scope_string;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + pkg_length
+    })
 }
diff --git a/src/acpi/aml/namestring.rs b/src/acpi/aml/namestring.rs
index 8015a8ca8559a53421e5a38a72544f3476d706a2..8464b6ccf8fbf932c6ea5cf8607637ec4e0f47a9 100644
--- a/src/acpi/aml/namestring.rs
+++ b/src/acpi/aml/namestring.rs
@@ -1,27 +1,22 @@
 use collections::vec::Vec;
 use collections::string::String;
 
-use super::AmlInternalError;
-
-use super::dataobj::{parse_arg_obj, parse_local_obj, ArgObj, LocalObj};
-use super::type2opcode::{parse_type6_opcode, Type6OpCode};
-
-#[derive(Debug, Clone)]
-pub enum SuperName {
-    NameString(String),
-    ArgObj(ArgObj),
-    LocalObj(LocalObj),
-    DebugObj,
-    Type6OpCode(Type6OpCode)
-}
-
-#[derive(Debug, Clone)]
-pub enum Target {
-    SuperName(SuperName),
-    Null
-}
-
-pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalError> {
+use super::AmlError;
+use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
+use super::namespace::AmlValue;
+use super::dataobj::{parse_arg_obj, parse_local_obj};
+use super::type2opcode::parse_type6_opcode;
+
+pub fn parse_name_string(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     let mut characters: Vec<u8> = vec!();
     let mut starting_index: usize = 0;
 
@@ -36,7 +31,7 @@ pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalErro
     }
 
     let sel = |data| {
-        parser_selector! {
+        parser_selector_simple! {
             data,
             parse_dual_name_path,
             parse_multi_name_path,
@@ -44,7 +39,7 @@ pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalErro
             parse_name_seg
         };
 
-        Err(AmlInternalError::AmlInvalidOpCode)
+        Err(AmlError::AmlInvalidOpCode)
     };
     let (mut chr, len) = sel(&data[starting_index..])?;
     characters.append(&mut chr);
@@ -52,35 +47,38 @@ pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalErro
     let name_string = String::from_utf8(characters);
 
     match name_string {
-        Ok(s) => Ok((s.clone(), len + starting_index)),
-        Err(_) => Err(AmlInternalError::AmlParseError("Namestring - Name is invalid"))
+        Ok(s) => Ok(AmlParseType {
+            val: AmlValue::String(s.clone()),
+            len: len + starting_index
+        }),
+        Err(_) => Err(AmlError::AmlParseError("Namestring - Name is invalid"))
     }
 }
 
-fn parse_null_name(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+fn parse_null_name(data: &[u8]) -> Result<(Vec<u8>, usize), AmlError> {
     parser_opcode!(data, 0x00);
     Ok((vec!(), 1 as usize))
 }
 
-pub fn parse_name_seg(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+pub fn parse_name_seg(data: &[u8]) -> Result<(Vec<u8>, usize), AmlError> {
     match data[0] {
         0x41 ... 0x5A | 0x5F => (),
-        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+        _ => return Err(AmlError::AmlInvalidOpCode)
     }
 
     match data[1] {
         0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
-        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+        _ => return Err(AmlError::AmlInvalidOpCode)
     }
 
     match data[2] {
         0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
-        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+        _ => return Err(AmlError::AmlInvalidOpCode)
     }
 
     match data[3] {
         0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
-        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+        _ => return Err(AmlError::AmlInvalidOpCode)
     }
 
     let mut name_seg = vec!(data[0], data[1], data[2], data[3]);
@@ -91,7 +89,7 @@ pub fn parse_name_seg(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError>
     Ok((name_seg, 4 as usize))
 }
 
-fn parse_dual_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+fn parse_dual_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlError> {
     parser_opcode!(data, 0x2E);
 
     let mut characters: Vec<u8> = vec!();
@@ -118,12 +116,12 @@ fn parse_dual_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalErro
     Ok((characters, dual_len))
 }
 
-fn parse_multi_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+fn parse_multi_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlError> {
     parser_opcode!(data, 0x2F);
 
     let seg_count = data[1];
     if seg_count == 0x00 {
-        return Err(AmlInternalError::AmlParseError("MultiName Path - can't have zero name segments"));
+        return Err(AmlError::AmlParseError("MultiName Path - can't have zero name segments"));
     }
 
     let mut current_seg = 0;
@@ -149,40 +147,80 @@ fn parse_multi_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalErr
     Ok((characters, multi_len))
 }
 
-pub fn parse_super_name(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+pub fn parse_super_name(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
+        data, ctx,
         parse_simple_name,
-        parser_wrap!(SuperName::Type6OpCode, parse_type6_opcode),
+        parse_type6_opcode,
         parse_debug_obj
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-fn parse_debug_obj(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+fn parse_debug_obj(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x31);
-    Ok((SuperName::DebugObj, 2 as usize))
+
+    Ok(AmlParseType {
+        val: AmlValue::DebugObject,
+        len: 2 as usize
+    })
 }
 
-pub fn parse_simple_name(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+pub fn parse_simple_name(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
-        parser_wrap!(SuperName::NameString, parse_name_string),
-        parser_wrap!(SuperName::ArgObj, parse_arg_obj),
-        parser_wrap!(SuperName::LocalObj, parse_local_obj)
+        data, ctx,
+        parse_name_string,
+        parse_arg_obj,
+        parse_local_obj
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_target(data: &[u8]) -> Result<(Target, usize), AmlInternalError> {
+pub fn parse_target(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     if data[0] == 0x00 {
-        Ok((Target::Null, 1 as usize))
+        Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 1 as usize
+        })
     } else {
-        match parse_super_name(data) {
-            Ok((name, name_len)) => Ok((Target::SuperName(name), name_len)),
-            Err(e) => Err(e)
-        }
+        parse_super_name(data, ctx)
     }
 }
diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs
new file mode 100644
index 0000000000000000000000000000000000000000..13c51a935e4b8883d7e609e84cba7261e09e2abc
--- /dev/null
+++ b/src/acpi/aml/parser.rs
@@ -0,0 +1,553 @@
+use collections::string::String;
+use collections::btree_map::BTreeMap;
+use collections::vec::Vec;
+use alloc::boxed::Box;
+
+use spin::RwLockWriteGuard;
+
+use super::namespace::{ AmlValue, ObjectReference };
+use super::AmlError;
+
+use acpi::ACPI_TABLE;
+
+pub type ParseResult = Result<AmlParseType, AmlError>;
+pub type AmlParseType = AmlParseTypeGeneric<AmlValue>;
+
+pub struct AmlParseTypeGeneric<T> {
+    pub val: T,
+    pub len: usize
+}
+
+pub enum ExecutionState {
+    EXECUTING,
+    CONTINUE,
+    BREAK,
+    RETURN(AmlValue)
+}
+
+pub struct AmlExecutionContext {
+    pub scope: String,
+    pub local_vars: [AmlValue; 8],
+    pub arg_vars: [AmlValue; 8],
+    pub state: ExecutionState,
+    pub namespace_delta: Vec<String>,
+    pub ctx_id: u64,
+    pub sync_level: u8
+}
+
+impl AmlExecutionContext {
+    pub fn new(scope: String) -> AmlExecutionContext {
+        let mut idptr = ACPI_TABLE.next_ctx.write();
+        let id: u64 = *idptr;
+
+        *idptr += 1;
+        
+        AmlExecutionContext {
+            scope: scope,
+            local_vars: [AmlValue::Uninitialized,
+                         AmlValue::Uninitialized,
+                         AmlValue::Uninitialized,
+                         AmlValue::Uninitialized,
+                         AmlValue::Uninitialized,
+                         AmlValue::Uninitialized,
+                         AmlValue::Uninitialized,
+                         AmlValue::Uninitialized],
+            arg_vars: [AmlValue::Uninitialized,
+                       AmlValue::Uninitialized,
+                       AmlValue::Uninitialized,
+                       AmlValue::Uninitialized,
+                       AmlValue::Uninitialized,
+                       AmlValue::Uninitialized,
+                       AmlValue::Uninitialized,
+                       AmlValue::Uninitialized],
+            state: ExecutionState::EXECUTING,
+            namespace_delta: vec!(),
+            ctx_id: id,
+            sync_level: 0
+        }
+    }
+
+    pub fn wait_for_event(&mut self, event_ptr: AmlValue) -> Result<bool, AmlError> {
+        let mut namespace_ptr = self.prelock();
+        let mut namespace = match *namespace_ptr {
+            Some(ref mut n) => n,
+            None => return Err(AmlError::AmlHardFatal)
+        };
+        
+        let mutex_idx = match event_ptr {
+            AmlValue::String(ref s) => s.clone(),
+            AmlValue::ObjectReference(ref o) => match *o {
+                ObjectReference::Object(ref s) => s.clone(),
+                _ => return Err(AmlError::AmlValueError)
+            },
+            _ => return Err(AmlError::AmlValueError)
+        };
+
+        let mutex = match namespace.get(&mutex_idx) {
+            Some(s) => s.clone(),
+            None => return Err(AmlError::AmlValueError)
+        };
+
+        match mutex {
+            AmlValue::Event(count) => {
+                if count > 0 {
+                    namespace.insert(mutex_idx, AmlValue::Event(count - 1));
+                    return Ok(true);
+                }
+            },
+            _ => return Err(AmlError::AmlValueError)
+        }
+
+        Ok(false)
+    }
+
+    pub fn signal_event(&mut self, event_ptr: AmlValue) -> Result<(), AmlError> {
+        let mut namespace_ptr = self.prelock();
+        let mut namespace = match *namespace_ptr {
+            Some(ref mut n) => n,
+            None => return Err(AmlError::AmlHardFatal)
+        };
+
+        
+        let mutex_idx = match event_ptr {
+            AmlValue::String(ref s) => s.clone(),
+            AmlValue::ObjectReference(ref o) => match *o {
+                ObjectReference::Object(ref s) => s.clone(),
+                _ => return Err(AmlError::AmlValueError)
+            },
+            _ => return Err(AmlError::AmlValueError)
+        };
+
+        let mutex = match namespace.get(&mutex_idx) {
+            Some(s) => s.clone(),
+            None => return Err(AmlError::AmlValueError)
+        };
+
+        match mutex {
+            AmlValue::Event(count) => {
+                namespace.insert(mutex_idx, AmlValue::Event(count + 1));
+                return Ok(());
+            },
+            _ => return Err(AmlError::AmlValueError)
+        }
+
+        Ok(())
+    }
+    
+    pub fn release_mutex(&mut self, mutex_ptr: AmlValue) -> Result<(), AmlError> {
+        let id = self.ctx_id;
+        
+        let mut namespace_ptr = self.prelock();
+        let mut namespace = match *namespace_ptr {
+            Some(ref mut n) => n,
+            None => return Err(AmlError::AmlHardFatal)
+        };
+        
+        let mutex_idx = match mutex_ptr {
+            AmlValue::String(ref s) => s.clone(),
+            AmlValue::ObjectReference(ref o) => match *o {
+                ObjectReference::Object(ref s) => s.clone(),
+                _ => return Err(AmlError::AmlValueError)
+            },
+            _ => return Err(AmlError::AmlValueError)
+        };
+
+        let mutex = match namespace.get(&mutex_idx) {
+            Some(s) => s.clone(),
+            None => return Err(AmlError::AmlValueError)
+        };
+        
+        match mutex {
+            AmlValue::Mutex((sync_level, owner)) => {
+                if let Some(o) = owner {
+                    if o == id {
+                        if sync_level == self.sync_level {
+                            namespace.insert(mutex_idx, AmlValue::Mutex((sync_level, None)));
+                            return Ok(());
+                        } else {
+                            return Err(AmlError::AmlValueError);
+                        }
+                    } else {
+                        return Err(AmlError::AmlHardFatal);
+                    }
+                }
+            },
+            AmlValue::OperationRegion(ref region) => {
+                if let Some(o) = region.accessed_by {
+                    if o == id {
+                        let mut new_region = region.clone();
+                        new_region.accessed_by = None;
+                        
+                        namespace.insert(mutex_idx, AmlValue::OperationRegion(new_region));
+                        return Ok(());
+                    } else {
+                        return Err(AmlError::AmlHardFatal);
+                    }
+                }
+            },
+            _ => return Err(AmlError::AmlValueError)
+        }
+
+        Ok(())
+    }
+
+    pub fn acquire_mutex(&mut self, mutex_ptr: AmlValue) -> Result<bool, AmlError> {
+        let id = self.ctx_id;        
+        
+        let mut namespace_ptr = self.prelock();
+        let mut namespace = match *namespace_ptr {
+            Some(ref mut n) => n,
+            None => return Err(AmlError::AmlHardFatal)
+        };
+        let mutex_idx = match mutex_ptr {
+            AmlValue::String(ref s) => s.clone(),
+            AmlValue::ObjectReference(ref o) => match *o {
+                ObjectReference::Object(ref s) => s.clone(),
+                _ => return Err(AmlError::AmlValueError)
+            },
+            _ => return Err(AmlError::AmlValueError)
+        };
+
+        let mutex = match namespace.get(&mutex_idx) {
+            Some(s) => s.clone(),
+            None => return Err(AmlError::AmlValueError)
+        };
+        
+        match mutex {
+            AmlValue::Mutex((sync_level, owner)) => {
+                if owner == None {
+                    if sync_level < self.sync_level {
+                        return Err(AmlError::AmlValueError);
+                    }
+                    
+                    namespace.insert(mutex_idx, AmlValue::Mutex((sync_level, Some(id))));
+                    self.sync_level = sync_level;
+                    
+                    return Ok(true);
+                }
+            },
+            AmlValue::OperationRegion(ref o) => {
+                if o.accessed_by == None {
+                    let mut new_region = o.clone();
+                    new_region.accessed_by = Some(id);
+
+                    namespace.insert(mutex_idx, AmlValue::OperationRegion(new_region));
+                    return Ok(true);
+                }
+            },
+            _ => return Err(AmlError::AmlValueError)
+        }
+
+        Ok(false)
+    }
+
+    pub fn add_to_namespace(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> {
+        let mut namespace = ACPI_TABLE.namespace.write();
+        
+        if let Some(ref mut namespace) = *namespace {
+            if let Some(obj) = namespace.get(&name) {
+                match *obj {
+                    AmlValue::Uninitialized => (),
+                    AmlValue::Method(ref m) => {
+                        if m.term_list.len() != 0 {
+                            return Err(AmlError::AmlValueError);
+                        }
+                    },
+                    _ => return Err(AmlError::AmlValueError)
+                }
+            }
+            
+            self.namespace_delta.push(name.clone());
+            namespace.insert(name, value);
+
+            Ok(())
+        } else {
+            Err(AmlError::AmlValueError)
+        }
+    }
+
+    pub fn clean_namespace(&mut self) {
+        let mut namespace = ACPI_TABLE.namespace.write();
+
+        if let Some(ref mut namespace) = *namespace {
+            for k in &self.namespace_delta {
+                namespace.remove(k);
+            }
+        }
+    }
+
+    pub fn init_arg_vars(&mut self, parameters: Vec<AmlValue>) {
+        if parameters.len() > 8 {
+            return;
+        }
+
+        let mut cur = 0;
+        while cur < parameters.len() {
+            self.arg_vars[cur] = parameters[cur].clone();
+            cur += 1;
+        }
+    }
+
+    pub fn prelock(&mut self) -> RwLockWriteGuard<'static, Option<BTreeMap<String, AmlValue>>> {
+        ACPI_TABLE.namespace.write()
+    }
+
+    fn modify_local_obj(&mut self, local: usize, value: AmlValue) -> Result<(), AmlError> {
+        self.local_vars[local] = value.get_as_type(self.local_vars[local].clone())?;
+        Ok(())
+    }
+
+    fn modify_object(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> {
+        if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() {
+            let coercion_obj = {
+                let obj = namespace.get(&name);
+
+                if let Some(o) = obj {
+                    o.clone()
+                } else {
+                    AmlValue::Uninitialized
+                }
+            };
+
+            namespace.insert(name, value.get_as_type(coercion_obj)?);
+            Ok(())
+        } else {
+            Err(AmlError::AmlHardFatal)
+        }
+    }
+
+    fn modify_index_final(&mut self, name: String, value: AmlValue, indices: Vec<u64>) -> Result<(), AmlError> {
+        if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() {
+            let mut obj = if let Some(s) = namespace.get(&name) {
+                s.clone()
+            } else {
+                return Err(AmlError::AmlValueError);
+            };
+
+            obj = self.modify_index_core(obj, value, indices)?;
+
+            namespace.insert(name, obj);
+            Ok(())
+        } else {
+            Err(AmlError::AmlValueError)
+        }
+    }
+
+    fn modify_index_core(&mut self, obj: AmlValue, value: AmlValue, indices: Vec<u64>) -> Result<AmlValue, AmlError> {
+        match obj {
+            AmlValue::String(ref string) => {
+                if indices.len() != 1 {
+                    return Err(AmlError::AmlValueError);
+                }
+                
+                let mut bytes = string.clone().into_bytes();
+                bytes[indices[0] as usize] = value.get_as_integer()? as u8;
+                
+                let string = String::from_utf8(bytes).unwrap();
+
+                Ok(AmlValue::String(string))
+            },
+            AmlValue::Buffer(ref b) => {
+                if indices.len() != 1 {
+                    return Err(AmlError::AmlValueError);
+                }
+                
+                let mut b = b.clone();
+                b[indices[0] as usize] = value.get_as_integer()? as u8;
+
+                Ok(AmlValue::Buffer(b))
+            },
+            AmlValue::BufferField(ref b) => {
+                if indices.len() != 1 {
+                    return Err(AmlError::AmlValueError);
+                }
+
+                let mut idx = indices[0];
+                idx += b.index.get_as_integer()?;
+
+                self.modify(AmlValue::ObjectReference(ObjectReference::Index(b.source_buf.clone(), Box::new(AmlValue::Integer(idx.clone())))), value);
+
+                Ok(AmlValue::BufferField(b.clone()))
+            },
+            AmlValue::Package(ref p) => {
+                if indices.len() < 0 {
+                    return Err(AmlError::AmlValueError);
+                }
+                
+                let mut p = p.clone();
+
+                if indices.len() == 1 {
+                    p[indices[0] as usize] = value;
+                } else {
+                    p[indices[0] as usize] = self.modify_index_core(p[indices[0] as usize].clone(), value, indices[1..].to_vec())?;
+                }
+                
+                Ok(AmlValue::Package(p))
+            },
+            _ => return Err(AmlError::AmlValueError)
+        }
+    }
+
+    pub fn modify_index(&mut self, name: AmlValue, value: AmlValue, indices: Vec<u64>) -> Result<(), AmlError>{
+        match name {
+            AmlValue::ObjectReference(r) => match r {
+                ObjectReference::Object(s) => self.modify_index_final(s, value, indices),
+                ObjectReference::Index(c, v) => {
+                    let mut indices = indices.clone();
+                    indices.push(v.get_as_integer()?);
+
+                    self.modify_index(*c, value, indices)
+                },
+                ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
+                ObjectReference::LocalObj(i) => {
+                    let v = self.local_vars[i as usize].clone();
+                    self.local_vars[i as usize] = self.modify_index_core(v, value, indices)?;
+
+                    Ok(())
+                }
+            },
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+
+    pub fn modify(&mut self, name: AmlValue, value: AmlValue) -> Result<(), AmlError> {
+        match name {
+            AmlValue::ObjectReference(r) => match r {
+                ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
+                ObjectReference::LocalObj(i) => self.modify_local_obj(i as usize, value),
+                ObjectReference::Object(s) => self.modify_object(s, value),
+                ObjectReference::Index(c, v) => self.modify_index(*c, value, vec!(v.get_as_integer()?))
+            },
+            AmlValue::String(s) => self.modify_object(s, value),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+
+    fn copy_local_obj(&mut self, local: usize, value: AmlValue) -> Result<(), AmlError> {
+        self.local_vars[local] = value;
+        Ok(())
+    }
+
+    fn copy_object(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> {
+        if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() {
+            namespace.insert(name, value);
+            Ok(())
+        } else {
+            Err(AmlError::AmlHardFatal)
+        }
+    }
+
+    pub fn copy(&mut self, name: AmlValue, value: AmlValue) -> Result<(), AmlError> {
+        match name {
+            AmlValue::ObjectReference(r) => match r {
+                ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
+                ObjectReference::LocalObj(i) => self.copy_local_obj(i as usize, value),
+                ObjectReference::Object(s) => self.copy_object(s, value),
+                ObjectReference::Index(c, v) => self.modify_index(*c, value, vec!(v.get_as_integer()?))
+            },
+            AmlValue::String(s) => self.copy_object(s, value),
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+
+    fn get_index_final(&self, name: String, indices: Vec<u64>) -> Result<AmlValue, AmlError> {
+        if let Some(ref namespace) = *ACPI_TABLE.namespace.read() {
+            let obj = if let Some(s) = namespace.get(&name) {
+                s.clone()
+            } else {
+                return Err(AmlError::AmlValueError);
+            };
+
+            self.get_index_core(obj, indices)
+        } else {
+            Err(AmlError::AmlValueError)
+        }
+    }
+
+    fn get_index_core(&self, obj: AmlValue, indices: Vec<u64>) -> Result<AmlValue, AmlError> {
+        match obj {
+            AmlValue::String(ref string) => {
+                if indices.len() != 1 {
+                    return Err(AmlError::AmlValueError);
+                }
+                
+                let mut bytes = string.clone().into_bytes();
+                Ok(AmlValue::Integer(bytes[indices[0] as usize] as u64))
+            },
+            AmlValue::Buffer(ref b) => {
+                if indices.len() != 1 {
+                    return Err(AmlError::AmlValueError);
+                }
+
+                Ok(AmlValue::Integer(b[indices[0] as usize] as u64))
+            },
+            AmlValue::BufferField(ref b) => {
+                if indices.len() != 1 {
+                    return Err(AmlError::AmlValueError);
+                }
+
+                let mut idx = indices[0];
+                idx += b.index.get_as_integer()?;
+
+                Ok(AmlValue::Integer(b.source_buf.get_as_buffer()?[idx as usize] as u64))
+            },
+            AmlValue::Package(ref p) => {
+                if indices.len() < 0 {
+                    return Err(AmlError::AmlValueError);
+                }
+
+                if indices.len() == 1 {
+                    Ok(p[indices[0] as usize].clone())
+                } else {
+                    self.get_index_core(p[indices[0] as usize].clone(), indices[1..].to_vec())
+                }
+            },
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+
+    pub fn get_index(&self, name: AmlValue, indices: Vec<u64>) -> Result<AmlValue, AmlError>{
+        match name {
+            AmlValue::ObjectReference(r) => match r {
+                ObjectReference::Object(s) => self.get_index_final(s, indices),
+                ObjectReference::Index(c, v) => {
+                    let mut indices = indices.clone();
+                    indices.push(v.get_as_integer()?);
+
+                    self.get_index(*c, indices)
+                },
+                ObjectReference::ArgObj(_) => Err(AmlError::AmlValueError),
+                ObjectReference::LocalObj(i) => {
+                    let v = self.local_vars[i as usize].clone();
+                    self.get_index_core(v, indices)
+                }
+            },
+            _ => Err(AmlError::AmlValueError)
+        }
+    }
+
+    pub fn get(&self, name: AmlValue) -> Result<AmlValue, AmlError> {
+        Ok(match name {
+            AmlValue::ObjectReference(r) => match r {
+                ObjectReference::ArgObj(i) => self.arg_vars[i as usize].clone(),
+                ObjectReference::LocalObj(i) => self.local_vars[i as usize].clone(),
+                ObjectReference::Object(ref s) => if let Some(ref namespace) = *ACPI_TABLE.namespace.read() {
+                    if let Some(o) = namespace.get(s) {
+                        o.clone()
+                    } else {
+                        AmlValue::None
+                    }
+                } else { AmlValue::None },
+                ObjectReference::Index(c, v) => self.get_index(*c, vec!(v.get_as_integer()?))?,
+            },
+            AmlValue::String(ref s) => if let Some(ref namespace) = *ACPI_TABLE.namespace.read() {
+                if let Some(o) = namespace.get(s) {
+                    o.clone()
+                } else {
+                    AmlValue::None
+                }
+            } else { AmlValue::None },
+            _ => AmlValue::None
+        })
+    }
+}
diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs
index 50e3aed575cc59feb62baca60c2e5db7636c92b3..31a23386ffc232dbc87b74d8b5b6a8005db25563 100644
--- a/src/acpi/aml/parsermacros.rs
+++ b/src/acpi/aml/parsermacros.rs
@@ -1,40 +1,43 @@
 #[macro_export]
 macro_rules! parser_selector {
-    {$data:expr, $func:expr} => {
-        match $func($data) {
+    {$data:expr, $ctx:expr, $func:expr} => {
+        match $func($data, $ctx) {
             Ok(res) => return Ok(res),
-            Err(AmlInternalError::AmlInvalidOpCode) => (),
+            Err(AmlError::AmlInvalidOpCode) => (),
             Err(e) => return Err(e)
         }
     };
-    {$data:expr, $func:expr, $($funcs:expr),+} => {
-        parser_selector! {$data, $func};
-        parser_selector! {$data, $($funcs),*};
+    {$data:expr, $ctx:expr, $func:expr, $($funcs:expr),+} => {
+        parser_selector! {$data, $ctx, $func};
+        parser_selector! {$data, $ctx, $($funcs),*};
     };
 }
 
 #[macro_export]
-macro_rules! parser_wrap {
-    ($wrap:expr, $func:expr) => {
-        |data| { 
-            match $func(data) {
-                Ok((res, size)) => Ok(($wrap(res), size)),
-                Err(e) => Err(e)
-            }
+macro_rules! parser_selector_simple {
+    {$data:expr, $func:expr} => {
+        match $func($data) {
+            Ok(res) => return Ok(res),
+            Err(AmlError::AmlInvalidOpCode) => (),
+            Err(e) => return Err(e)
         }
     };
+    {$data:expr, $func:expr, $($funcs:expr),+} => {
+        parser_selector_simple! {$data, $func};
+        parser_selector_simple! {$data, $($funcs),*};
+    };
 }
 
 #[macro_export]
 macro_rules! parser_opcode {
     ($data:expr, $opcode:expr) => {
         if $data[0] != $opcode {
-            return Err(AmlInternalError::AmlInvalidOpCode);
+            return Err(AmlError::AmlInvalidOpCode);
         }
     };
     ($data:expr, $opcode:expr, $alternate_opcode:expr) => {
         if $data[0] != $opcode && $data[0] != $alternate_opcode {
-            return Err(AmlInternalError::AmlInvalidOpCode);
+            return Err(AmlError::AmlInvalidOpCode);
         }
     };
 }
@@ -43,7 +46,7 @@ macro_rules! parser_opcode {
 macro_rules! parser_opcode_extended {
     ($data:expr, $opcode:expr) => {
         if $data[0] != 0x5B || $data[1] != $opcode {
-            return Err(AmlInternalError::AmlInvalidOpCode);
+            return Err(AmlError::AmlInvalidOpCode);
         }
     };
 }
diff --git a/src/acpi/aml/pkglength.rs b/src/acpi/aml/pkglength.rs
index 7c4ace8d124aea4f64ac9bc7c8740d38449451a4..b93939f0da8dac6301628475b07f120397b54cc9 100644
--- a/src/acpi/aml/pkglength.rs
+++ b/src/acpi/aml/pkglength.rs
@@ -1,6 +1,6 @@
-use super::AmlInternalError;
+use super::AmlError;
 
-pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlInternalError> {
+pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlError> {
     let lead_byte = data[0];
     let count_bytes: usize = (lead_byte >> 6) as usize;
 
@@ -10,7 +10,7 @@ pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlInternalError>
 
     let upper_two = (lead_byte >> 4) & 0x03;
     if upper_two != 0 {
-        return Err(AmlInternalError::AmlParseError("Invalid package length"));
+        return Err(AmlError::AmlParseError("Invalid package length"));
     }
 
     let mut current_byte = 0;
diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs
index b236584e10895b0a352e1d961c81692e8b969c62..262f731263ddf59cbb92973016439d88e2ed1f29 100644
--- a/src/acpi/aml/termlist.rs
+++ b/src/acpi/aml/termlist.rs
@@ -1,135 +1,174 @@
-use alloc::boxed::Box;
-use collections::string::String;
 use collections::vec::Vec;
 
-use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, get_namespace_string};
-use super::namespacemodifier::{parse_namespace_modifier, NamespaceModifier};
-use super::namedobj::{parse_named_obj, NamedObj};
-use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj, DataObj, ArgObj, LocalObj};
-use super::type1opcode::{parse_type1_opcode, Type1OpCode};
-use super::type2opcode::{parse_type2_opcode, Type2OpCode};
+use super::AmlError;
+use super::parser::{ AmlParseType, ParseResult, AmlExecutionContext, ExecutionState };
+use super::namespace::{AmlValue, get_namespace_string};
+use super::namespacemodifier::parse_namespace_modifier;
+use super::namedobj::parse_named_obj;
+use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj};
+use super::type1opcode::parse_type1_opcode;
+use super::type2opcode::parse_type2_opcode;
 use super::namestring::parse_name_string;
 
-#[derive(Debug, Clone)]
-pub enum TermArg {
-    LocalObj(Box<LocalObj>),
-    DataObj(Box<DataObj>),
-    ArgObj(Box<ArgObj>),
-    Type2Opcode(Box<Type2OpCode>)
-}
-
-#[derive(Debug, Clone)]
-pub enum TermObj {
-    NamespaceModifier(Box<NamespaceModifier>),
-    NamedObj(Box<NamedObj>),
-    Type1Opcode(Box<Type1OpCode>),
-    Type2Opcode(Box<Type2OpCode>)
-}
-
-#[derive(Debug, Clone)]
-pub enum Object {
-    NamespaceModifier(Box<NamespaceModifier>),
-    NamedObj(Box<NamedObj>)
-}
-
-#[derive(Debug, Clone)]
-pub struct MethodInvocation {
-
-}
-
-impl AmlExecutable for Vec<TermObj> {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        for term in self {
-            term.execute(namespace, scope.clone());
-        }
-
-        None
-    }
-}
-
-impl AmlExecutable for TermArg {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            TermArg::LocalObj(ref l) => Some(AmlValue::Integer),
-            TermArg::DataObj(ref d) => d.execute(namespace, scope),
-            TermArg::ArgObj(ref a) => Some(AmlValue::Integer),
-            TermArg::Type2Opcode(ref o) => Some(AmlValue::Integer)
-        }
-    }
-}
-
-impl AmlExecutable for TermObj {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            TermObj::NamespaceModifier(ref res) => res.execute(namespace, scope.clone()),
-            TermObj::NamedObj(ref res) => res.execute(namespace, scope.clone()),
-            TermObj::Type1Opcode(ref res) => res.execute(namespace, scope.clone()),
-            TermObj::Type2Opcode(ref res) => res.execute(namespace, scope.clone())
-        }
+pub fn parse_term_list(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
-}
-
-pub fn parse_term_list(data: &[u8]) -> Result<Vec<TermObj>, AmlInternalError> {
-    let mut terms: Vec<TermObj> = vec!();
+    
     let mut current_offset: usize = 0;
 
     while current_offset < data.len() {
-        let (res, len) = parse_term_obj(&data[current_offset..])?;
-        terms.push(res);
-        current_offset += len;
+        let res = parse_term_obj(&data[current_offset..], ctx)?;
+        
+        match ctx.state {
+            ExecutionState::EXECUTING => (),
+            _ => return Ok(AmlParseType {
+                val: AmlValue::None,
+                len: data.len()
+            })
+        }
+    
+        current_offset += res.len;
     }
 
-    Ok(terms)
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: data.len()
+    })
 }
 
-pub fn parse_term_arg(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> {
+pub fn parse_term_arg(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
-        parser_wrap!(TermArg::LocalObj, parser_wrap!(Box::new, parse_local_obj)),
-        parser_wrap!(TermArg::DataObj, parser_wrap!(Box::new, parse_data_obj)),
-        parser_wrap!(TermArg::ArgObj, parser_wrap!(Box::new, parse_arg_obj)),
-        parser_wrap!(TermArg::Type2Opcode, parser_wrap!(Box::new, parse_type2_opcode))
+        data, ctx,
+        parse_local_obj,
+        parse_data_obj,
+        parse_arg_obj,
+        parse_type2_opcode
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_object_list(data: &[u8]) -> Result<Vec<Object>, AmlInternalError> {
-    let mut terms: Vec<Object> = vec!();
+pub fn parse_object_list(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     let mut current_offset: usize = 0;
 
     while current_offset < data.len() {
-        let (res, len) = parse_object(&data[current_offset..])?;
-        terms.push(res);
-        current_offset += len;
+        let res = parse_object(&data[current_offset..], ctx)?;
+        
+        match ctx.state {
+            ExecutionState::EXECUTING => (),
+            _ => return Ok(AmlParseType {
+                val: AmlValue::None,
+                len: data.len()
+            })
+        }
+    
+        current_offset += res.len;
     }
 
-    Ok(terms)
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: data.len()
+    })
 }
 
-fn parse_object(data: &[u8]) -> Result<(Object, usize), AmlInternalError> {
+fn parse_object(data: &[u8],
+                ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
-        parser_wrap!(Object::NamespaceModifier, parser_wrap!(Box::new, parse_namespace_modifier)),
-        parser_wrap!(Object::NamedObj, parser_wrap!(Box::new, parse_named_obj))
+        data, ctx,
+        parse_namespace_modifier,
+        parse_named_obj
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_method_invocation(data: &[u8]) -> Result<(MethodInvocation, usize), AmlInternalError> {
-    let (name, name_len) = parse_name_string(data)?;
-    Err(AmlInternalError::AmlDeferredLoad)
+pub fn parse_method_invocation(data: &[u8],
+                               ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    let name = parse_name_string(data, ctx)?;
+    let method = ctx.get(name.val.clone())?;
+
+    let method = match method {
+        AmlValue::None => return Err(AmlError::AmlDeferredLoad),
+        _ => method.get_as_method()?
+    };
+    
+    let mut cur = 0;
+    let mut params: Vec<AmlValue> = vec!();
+
+    let mut current_offset = name.len;
+    
+    while cur < method.arg_count {
+        let res = parse_term_arg(&data[current_offset..], ctx)?;
+        
+        current_offset += res.len;
+        cur += 1;
+
+        params.push(res.val);
+    }
+
+    Ok(AmlParseType {
+        val: method.execute(get_namespace_string(ctx.scope.clone(), name.val)?, params),
+        len: current_offset
+    })
 }
 
-fn parse_term_obj(data: &[u8]) -> Result<(TermObj, usize), AmlInternalError> {
+fn parse_term_obj(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
-        parser_wrap!(TermObj::NamespaceModifier, parser_wrap!(Box::new, parse_namespace_modifier)),
-        parser_wrap!(TermObj::NamedObj, parser_wrap!(Box::new, parse_named_obj)),
-        parser_wrap!(TermObj::Type1Opcode, parser_wrap!(Box::new, parse_type1_opcode)),
-        parser_wrap!(TermObj::Type2Opcode, parser_wrap!(Box::new, parse_type2_opcode))
+        data, ctx,
+        parse_namespace_modifier,
+        parse_named_obj,
+        parse_type1_opcode,
+        parse_type2_opcode
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs
index 103e5428483c7e2348d1f7e427b73ee015c21b4d..e5c702315118a13b799bfebed8b7826697f66325 100644
--- a/src/acpi/aml/type1opcode.rs
+++ b/src/acpi/aml/type1opcode.rs
@@ -1,77 +1,31 @@
-use alloc::boxed::Box;
-use collections::string::String;
-use collections::vec::Vec;
-
-use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace};
+use super::AmlError;
+use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
+use super::namespace::{AmlValue, ObjectReference, OperationRegion};
 use super::pkglength::parse_pkg_length;
-use super::termlist::{parse_term_arg, parse_term_list, TermObj, TermArg};
-use super::namestring::{parse_name_string, parse_super_name, SuperName};
-
-#[derive(Debug, Clone)]
-pub enum Type1OpCode {
-    DefBreak,
-    DefBreakPoint,
-    DefContinue,
-    DefFatal {
-        fatal_type: u8,
-        fatal_code: u16,
-        fatal_arg: TermArg
-    },
-    DefNoop,
-    DefIfElse {
-        if_block: IfBlock,
-        else_block: IfBlock
-    },
-    DefLoad {
-        name: String,
-        ddb_handle_object: SuperName
-    },
-    DefNotify {
-        object: SuperName,
-        value: TermArg
-    },
-    DefRelease(SuperName),
-    DefReset(SuperName),
-    DefSignal(SuperName),
-    DefSleep(TermArg),
-    DefStall(TermArg),
-    DefUnload(SuperName),
-    DefWhile {
-        predicate: TermArg,
-        block: Vec<TermObj>
-    },
-    DefReturn(TermArg),
-    DeferredLoad(Vec<u8>)
-}
-
-impl AmlExecutable for Type1OpCode {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        None
+use super::termlist::{parse_term_arg, parse_term_list};
+use super::namestring::{parse_name_string, parse_super_name};
+
+use time::monotonic;
+
+use acpi::{Sdt, load_table, get_sdt_signature};
+use super::{parse_aml_table, is_aml_table};
+
+pub fn parse_type1_opcode(data: &[u8],
+                          ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
-}
-
-#[derive(Debug, Clone)]
-pub enum IfBlock {
-    If {
-        predicate: TermArg,
-        if_block: Vec<TermObj>
-    },
-    Else(Vec<TermObj>),
-    NoBlock,
-    DeferredLoad(Vec<u8>)
-}
-
-pub fn parse_type1_opcode(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    match data[0] {
-        0xA5 => return Ok((Type1OpCode::DefBreak, 1 as usize)),
-        0xCC => return Ok((Type1OpCode::DefBreakPoint, 1 as usize)),
-        0x9F => return Ok((Type1OpCode::DefContinue, 1 as usize)),
-        0xA3 => return Ok((Type1OpCode::DefNoop, 1 as usize)),
-        _ => ()
-    }
-
+    
     parser_selector! {
-        data,
+        data, ctx,
+        parse_def_break,
+        parse_def_breakpoint,
+        parse_def_continue,
+        parse_def_noop,
         parse_def_fatal,
         parse_def_if_else,
         parse_def_load,
@@ -86,174 +40,433 @@ pub fn parse_type1_opcode(data: &[u8]) -> Result<(Type1OpCode, usize), AmlIntern
         parse_def_while
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-fn parse_def_fatal(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x32 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_break(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0xA5);
+    ctx.state = ExecutionState::BREAK;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 as usize
+    })
+}
 
-    let fatal_type = data[2];
-    let fatal_code: u16 = (data[3] as u16) +
-        ((data[4] as u16) << 8);
-    let (fatal_arg, fatal_arg_len) = parse_term_arg(&data[5..])?;
+fn parse_def_breakpoint(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode!(data, 0xCC);
 
-    Ok((Type1OpCode::DefFatal {fatal_type, fatal_code, fatal_arg}, fatal_arg_len + 5))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 as usize
+    })
 }
 
-fn parse_def_load(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x20 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_continue(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x9F);
+    ctx.state = ExecutionState::CONTINUE;
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 as usize
+    })
+}
 
-    let (name, name_len) = parse_name_string(&data[2..])?;
-    let (ddb_handle_object, ddb_handle_object_len) = parse_super_name(&data[2 + name_len..])?;
+fn parse_def_noop(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode!(data, 0xA3);
 
-    Ok((Type1OpCode::DefLoad {name, ddb_handle_object}, 2 + name_len + ddb_handle_object_len))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 as usize
+    })
 }
 
-fn parse_def_notify(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x86 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_fatal(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode_extended!(data, 0x32);
 
-    let (object, object_len) = parse_super_name(&data[1..])?;
-    let (value, value_len) = parse_term_arg(&data[1 + object_len..])?;
+    let fatal_type = data[2];
+    let fatal_code: u16 = (data[3] as u16) + ((data[4] as u16) << 8);
+    let fatal_arg = parse_term_arg(&data[5..], ctx)?;
 
-    Ok((Type1OpCode::DefNotify {object, value}, 1 + object_len + value_len))
+    Err(AmlError::AmlFatalError(fatal_type, fatal_code, fatal_arg.val))
 }
 
-fn parse_def_release(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x27 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_load(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x20);
+
+    let name = parse_name_string(&data[2..], ctx)?;
+    let ddb_handle_object = parse_super_name(&data[2 + name.len..], ctx)?;
+
+    let tbl = ctx.get(name.val)?.get_as_buffer()?;
+    let sdt = unsafe { &*(tbl.as_ptr() as *const Sdt) };
+
+    if is_aml_table(sdt) {
+        load_table(get_sdt_signature(sdt));
+        let delta = parse_aml_table(sdt)?;
+        ctx.modify(ddb_handle_object.val, AmlValue::DDBHandle((delta, get_sdt_signature(sdt))));
+        
+        Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 2 + name.len + ddb_handle_object.len
+        })
+    } else {
+        Err(AmlError::AmlValueError)
     }
-
-    let (object, object_len) = parse_super_name(&data[2..])?;
-
-    Ok((Type1OpCode::DefRelease(object), 2 + object_len))
 }
 
-fn parse_def_reset(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x26 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_notify(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x86);
 
-    let (object, object_len) = parse_super_name(&data[2..])?;
+    let object = parse_super_name(&data[1..], ctx)?;
+    let value = parse_term_arg(&data[1 + object.len..], ctx)?;
 
-    Ok((Type1OpCode::DefReset(object), 2 + object_len))
-}
+    let number = value.val.get_as_integer()? as u8;
 
-fn parse_def_signal(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x24 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+    match ctx.get(object.val)? {
+        AmlValue::Device(d) => {
+            if let Some(methods) = d.notify_methods.get(&number) {
+                for method in methods {
+                    method();
+                }
+            }
+        },
+        AmlValue::Processor(d) => {
+            if let Some(methods) = d.notify_methods.get(&number) {
+                for method in methods {
+                    method();
+                }
+            }
+        },
+        AmlValue::ThermalZone(d) => {
+            if let Some(methods) = d.notify_methods.get(&number) {
+                for method in methods {
+                    method();
+                }
+            }
+        },
+        _ => return Err(AmlError::AmlValueError)
     }
 
-    let (object, object_len) = parse_super_name(&data[2..])?;
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + object.len + value.len
+    })
+}
 
-    Ok((Type1OpCode::DefSignal(object), 2 + object_len))
+fn parse_def_release(data: &[u8],
+                     ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x27);
+
+    let obj = parse_super_name(&data[2..], ctx)?;
+    ctx.release_mutex(obj.val);
+    
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + obj.len
+    })
 }
 
-fn parse_def_sleep(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x22 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_reset(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode_extended!(data, 0x26);
+
+    let object = parse_super_name(&data[2..], ctx)?;
+    ctx.get(object.val.clone())?.get_as_event()?;
 
-    let (time, time_len) = parse_term_arg(&data[2..])?;
+    ctx.modify(object.val.clone(), AmlValue::Event(0));
 
-    Ok((Type1OpCode::DefSleep(time), 2 + time_len))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + object.len
+    })
 }
 
-fn parse_def_stall(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x21 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_signal(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode_extended!(data, 0x24);
+    let object = parse_super_name(&data[2..], ctx)?;
+
+    ctx.signal_event(object.val)?;
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + object.len
+    })
+}
 
-    let (time, time_len) = parse_term_arg(&data[2..])?;
+fn parse_def_sleep(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x22);
+
+    let time = parse_term_arg(&data[2..], ctx)?;
+    let timeout = time.val.get_as_integer()?;
+    
+    let (seconds, nanoseconds) = monotonic();
+    let starting_time_ns = nanoseconds + (seconds * 1000000000);
+    
+    loop {
+        let (seconds, nanoseconds) = monotonic();
+        let current_time_ns = nanoseconds + (seconds * 1000000000);
+        
+        if current_time_ns - starting_time_ns > timeout as u64 * 1000000 {
+            break;
+        }
+    }
 
-    Ok((Type1OpCode::DefStall(time), 2 + time_len))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + time.len
+    })
 }
 
-fn parse_def_unload(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x2A {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_stall(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x21);
+
+    let time = parse_term_arg(&data[2..], ctx)?;
+    let timeout = time.val.get_as_integer()?;
+    
+    let (seconds, nanoseconds) = monotonic();
+    let starting_time_ns = nanoseconds + (seconds * 1000000000);
+    
+    loop {
+        let (seconds, nanoseconds) = monotonic();
+        let current_time_ns = nanoseconds + (seconds * 1000000000);
+        
+        if current_time_ns - starting_time_ns > timeout as u64 * 1000 {
+            break;
+        }
     }
 
-    let (object, object_len) = parse_super_name(&data[2..])?;
-
-    Ok((Type1OpCode::DefUnload(object), 2 + object_len))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + time.len
+    })
 }
 
-fn parse_def_if_else(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0xA0 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_unload(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode_extended!(data, 0x2A);
 
-    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    let object = parse_super_name(&data[2..], ctx)?;
 
-    let if_block = match parse_term_arg(&data[1 + pkg_length_len..]) {
-        Ok((predicate, predicate_len)) => {
-            match parse_term_list(&data[1 + pkg_length_len + predicate_len .. 1 + pkg_length]) {
-                Ok(if_block) => IfBlock::If {predicate, if_block},
-                Err(AmlInternalError::AmlDeferredLoad) =>
-                    IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
-                Err(e) => return Err(e)
-            }
-        },
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
-        Err(e) => return Err(e)
-    };
+    let delta = ctx.get(object.val)?.get_as_ddb_handle()?;
+    let mut namespace = ctx.prelock();
 
-    let (else_block, else_block_len) = parse_def_else(&data[1 + pkg_length..])?;
+    if let Some(ref mut ns) = *namespace {
+        for o in delta.0 {
+            ns.remove(&o);
+        }
+    }
 
-    return Ok((Type1OpCode::DefIfElse {if_block, else_block},
-               pkg_length + else_block_len + 1));
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 2 + object.len
+    })
 }
 
-fn parse_def_else(data: &[u8]) -> Result<(IfBlock, usize), AmlInternalError> {
-    if data.len() == 0 || data[0] != 0xA1 {
-        // We might be at the very end of a buffer, in which case there isn't an else
-        return Ok((IfBlock::NoBlock, 0));
+fn parse_def_if_else(data: &[u8],
+                     ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0xA0);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-    match parse_term_list(&data[1 + pkg_length_len .. 1 + pkg_length]) {
-        Ok(term_list) => Ok((IfBlock::Else(term_list), 1 + pkg_length)),
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            Ok((IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
-        Err(e) => return Err(e)
+    let if_condition = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?;
+    
+    let (else_length, else_length_len) = if data.len() > 1 + pkg_length && data[1 + pkg_length] == 0xA1 {
+        parse_pkg_length(&data[2 + pkg_length..])?
+    } else {
+        (0 as usize, 0 as usize)
+    };
+
+    if if_condition.val.get_as_integer()? > 0 {
+        parse_term_list(&data[1 + pkg_length_len + if_condition.len .. 1 + pkg_length], ctx)?;
+    } else if else_length > 0 {
+        parse_term_list(&data[2 + pkg_length + else_length_len .. 2 + pkg_length + else_length], ctx)?;
     }
+
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + pkg_length + if else_length > 0 { 1 + else_length } else { 0 }
+    })
 }
 
-fn parse_def_while(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0xA2 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_while(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0xA2);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-    let (predicate, predicate_len) = match parse_term_arg(&data[1 + pkg_length_len..]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((Type1OpCode::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-    let block = match parse_term_list(&data[1 + pkg_length_len + predicate_len .. 1 + pkg_length]) {
-        Ok(p) => p,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((Type1OpCode::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
-        Err(e) => return Err(e)
-    };
 
-    Ok((Type1OpCode::DefWhile {predicate, block}, pkg_length + 1))
+    loop {
+        let predicate = parse_term_arg(&data[1 + pkg_length_len..], ctx)?;
+        if predicate.val.get_as_integer()? == 0 {
+            break;
+        }
+        
+        parse_term_list(&data[1 + pkg_length_len + predicate.len .. 1 + pkg_length], ctx)?;
+
+        match ctx.state {
+            ExecutionState::EXECUTING => (),
+            ExecutionState::BREAK => {
+                ctx.state = ExecutionState::EXECUTING;
+                break;
+            },
+            ExecutionState::CONTINUE => ctx.state = ExecutionState::EXECUTING,
+            _ => return Ok(AmlParseType {
+                val: AmlValue::None,
+                len: 0 as usize
+            })
+        }
+    }
+    
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + pkg_length
+    })
 }
 
-fn parse_def_return(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
-    if data[0] != 0xA4 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_return(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0xA4);
 
-    let (arg_object, arg_object_len) = parse_term_arg(&data[1..])?;
+    let arg_object = parse_term_arg(&data[1..], ctx)?;
+    ctx.state = ExecutionState::RETURN(arg_object.val);
 
-    Ok((Type1OpCode::DefReturn(arg_object), 1 + arg_object_len))
+    Ok(AmlParseType {
+        val: AmlValue::None,
+        len: 1 + arg_object.len
+    })
 }
diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs
index 744dbef502ce9b4b11b12bbf06fd71f8f43eb822..37b3001da1382534cc5b1da8947b6a56edf94a65 100644
--- a/src/acpi/aml/type2opcode.rs
+++ b/src/acpi/aml/type2opcode.rs
@@ -2,217 +2,16 @@ use alloc::boxed::Box;
 use collections::string::String;
 use collections::vec::Vec;
 
-use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace};
+use super::{AmlError, parse_aml_with_scope};
+use super::parser::{AmlParseType, ParseResult, AmlExecutionContext, ExecutionState};
+use super::namespace::{AmlValue, ObjectReference, OperationRegion};
 use super::pkglength::parse_pkg_length;
-use super::termlist::{parse_term_arg, parse_method_invocation, TermArg, MethodInvocation};
-use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name,
-                        SuperName, Target};
-use super::dataobj::{parse_data_ref_obj, DataRefObj};
+use super::termlist::{parse_term_arg, parse_method_invocation};
+use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name};
+use super::dataobj::parse_data_ref_obj;
 
-#[derive(Debug, Clone)]
-pub enum Type2OpCode {
-    DefAcquire {
-        object: SuperName,
-        timeout: u16
-    },
-    DefBuffer(DefBuffer),
-    DefPackage(DefPackage),
-    DefVarPackage(DefVarPackage),
-    DefDerefOf(TermArg),
-    DefRefOf(SuperName),
-    DefIncrement(SuperName),
-    DefIndex(DefIndex),
-    DefDecrement(SuperName),
-    DefFindSetLeftBit {
-        operand: TermArg,
-        target: Target
-    },
-    DefFindSetRightBit {
-        operand: TermArg,
-        target: Target
-    },
-    DefFromBCD {
-        operand: TermArg,
-        target: Target
-    },
-    DefDivide {
-        dividend: TermArg,
-        divisor: TermArg,
-        remainder: Target,
-        quotient: Target
-    },
-    DefCondRefOf {
-        operand: SuperName,
-        target: Target
-    },
-    DefCopyObject {
-        source: TermArg,
-        destination: SuperName
-    },
-    DefLAnd {
-        lhs: TermArg,
-        rhs: TermArg
-    },
-    DefLEqual {
-        lhs: TermArg,
-        rhs: TermArg
-    },
-    DefLGreater {
-        lhs: TermArg,
-        rhs: TermArg
-    },
-    DefLLess {
-        lhs: TermArg,
-        rhs: TermArg
-    },
-    DefLNot(TermArg),
-    DefLOr {
-        lhs: TermArg,
-        rhs: TermArg
-    },
-    DefSizeOf(SuperName),
-    DefStore {
-        operand: TermArg,
-        target: SuperName
-    },
-    DefSubtract {
-        minuend: TermArg,
-        subtrahend: TermArg,
-        target: Target
-    },
-    DefToBuffer {
-        operand: TermArg,
-        target: Target
-    },
-    DefToHexString {
-        operand: TermArg,
-        target: Target
-    },
-    DefToBCD {
-        operand: TermArg,
-        target: Target
-    },
-    DefToDecimalString {
-        operand: TermArg,
-        target: Target
-    },
-    DefToInteger {
-        operand: TermArg,
-        target: Target
-    },
-    DefToString {
-        operand: TermArg,
-        length: TermArg,
-        target: Target
-    },
-    DefConcat {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefConcatRes {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefShiftLeft {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefShiftRight {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefAdd {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefMultiply {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefMod {
-        dividend: TermArg,
-        divisor: TermArg,
-        target: Target
-    },
-    DefAnd {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefNAnd {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefOr {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefXor {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefNOr {
-        lhs: TermArg,
-        rhs: TermArg,
-        target: Target
-    },
-    DefNot {
-        operand: TermArg,
-        target: Target
-    },
-    DefLoadTable {
-        signature: TermArg,
-        oem_id: TermArg,
-        oem_table_id: TermArg,
-        root_path: TermArg,
-        parameter_path: TermArg,
-        parameter_data: TermArg
-    },
-    DefMatch {
-        search_pkg: TermArg,
-        first_operation: MatchOpcode,
-        first_operand: TermArg,
-        second_operation: MatchOpcode,
-        second_operand: TermArg,
-        start_index: TermArg
-    },
-    DefMid {
-        source: TermArg,
-        index: TermArg,
-        length: TermArg,
-        target: Target
-    },
-    DefWait {
-        event_object: SuperName,
-        operand: TermArg
-    },
-    DefObjectType(DefObjectType),
-    DefTimer,
-    MethodInvocation(MethodInvocation)
-}
-
-impl AmlExecutable for Type2OpCode {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        None
-    }
-}
-
-#[derive(Debug, Clone)]
-pub enum DefObjectType {
-    SuperName(SuperName),
-    DefIndex(DefIndex),
-    DefRefOf(SuperName),
-    DefDerefOf(TermArg)
-}
+use time::monotonic;
+use acpi::{ACPI_TABLE, SDT_POINTERS};
 
 #[derive(Debug, Clone)]
 pub enum MatchOpcode {
@@ -224,84 +23,18 @@ pub enum MatchOpcode {
     MGT
 }
 
-#[derive(Debug, Clone)]
-pub enum Type6OpCode {
-    DefDerefOf(TermArg),
-    DefRefOf(Box<SuperName>),
-    DefIndex(DefIndex),
-    MethodInvocation(MethodInvocation)
-}
-
-#[derive(Debug, Clone)]
-pub struct DefIndex {
-    obj: TermArg,
-    idx: TermArg,
-    target: Box<Target>
-}
-
-#[derive(Debug, Clone)]
-pub enum DefBuffer {
-    Buffer {
-        buffer_size: TermArg,
-        byte_list: Vec<u8>
-    },
-    DeferredLoad(Vec<u8>)
-}
-
-#[derive(Debug, Clone)]
-pub enum DefPackage {
-    Package {
-        num_elements: u8,
-        elements: Vec<PackageElement>
-    },
-    DeferredLoad(Vec<u8>)
-}
-
-#[derive(Debug, Clone)]
-pub enum DefVarPackage {
-    Package {
-        num_elements: TermArg,
-        elements: Vec<PackageElement>
-    },
-    DeferredLoad(Vec<u8>)
-}
-
-#[derive(Debug, Clone)]
-pub enum PackageElement {
-    DataRefObj(DataRefObj),
-    NameString(String)
-}
-
-impl AmlExecutable for DefPackage {
-    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
-        match *self {
-            DefPackage::Package { ref num_elements, ref elements } => {
-                let mut values: Vec<AmlValue> = vec!();
-
-                for element in elements {
-                    match *element {
-                        PackageElement::DataRefObj(ref d) => {
-                            let elem = match d.execute(namespace, scope.clone()) {
-                                Some(e) => e,
-                                None => continue
-                            };
-
-                            values.push(elem);
-                        },
-                        _ => return None
-                    }
-                }
-
-                Some(AmlValue::Package(values))
-            },
-            _ => None
-        }
+pub fn parse_type2_opcode(data: &[u8],
+                          ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
-}
-
-pub fn parse_type2_opcode(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    
     parser_selector! {
-        data,
+        data, ctx,
         parse_def_increment,
         parse_def_acquire,
         parse_def_wait,
@@ -344,589 +77,1703 @@ pub fn parse_type2_opcode(data: &[u8]) -> Result<(Type2OpCode, usize), AmlIntern
         parse_def_nor,
         parse_def_not,
         parse_def_timer,
-        parser_wrap!(Type2OpCode::DefBuffer, parse_def_buffer),
-        parser_wrap!(Type2OpCode::DefPackage, parse_def_package),
-        parser_wrap!(Type2OpCode::DefVarPackage, parse_def_var_package),
-        parser_wrap!(Type2OpCode::DefObjectType, parse_def_object_type),
-        parser_wrap!(Type2OpCode::DefDerefOf, parse_def_deref_of),
-        parser_wrap!(Type2OpCode::DefRefOf, parse_def_ref_of),
-        parser_wrap!(Type2OpCode::DefIndex, parse_def_index),
-        parser_wrap!(Type2OpCode::MethodInvocation, parse_method_invocation)
+        parse_def_buffer,
+        parse_def_package,
+        parse_def_var_package,
+        parse_def_object_type,
+        parse_def_deref_of,
+        parse_def_ref_of,
+        parse_def_index,
+        parse_method_invocation
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_type6_opcode(data: &[u8]) -> Result<(Type6OpCode, usize), AmlInternalError> {
+pub fn parse_type6_opcode(data: &[u8],
+                          ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_selector! {
-        data,
-        parser_wrap!(Type6OpCode::DefDerefOf, parse_def_deref_of),
-        parser_wrap!(Type6OpCode::DefRefOf, parser_wrap!(Box::new, parse_def_ref_of)),
-        parser_wrap!(Type6OpCode::DefIndex, parse_def_index),
-        parser_wrap!(Type6OpCode::MethodInvocation, parse_method_invocation)
+        data, ctx,
+        parse_def_deref_of,
+        parse_def_ref_of,
+        parse_def_index,
+        parse_method_invocation
     };
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_def_object_type(data: &[u8]) -> Result<(DefObjectType, usize), AmlInternalError> {
+pub fn parse_def_object_type(data: &[u8],
+                             ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x8E);
     parser_selector! {
-        data,
-        parser_wrap!(DefObjectType::SuperName, parse_super_name),
-        parser_wrap!(DefObjectType::DefRefOf, parse_def_ref_of),
-        parser_wrap!(DefObjectType::DefDerefOf, parse_def_deref_of),
-        parser_wrap!(DefObjectType::DefIndex, parse_def_index)
+        data, ctx,
+        parse_super_name,
+        parse_def_ref_of,
+        parse_def_deref_of,
+        parse_def_index
     }
 
-    Err(AmlInternalError::AmlInvalidOpCode)
+    Err(AmlError::AmlInvalidOpCode)
 }
 
-pub fn parse_def_package(data: &[u8]) -> Result<(DefPackage, usize), AmlInternalError> {
+pub fn parse_def_package(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: Handle deferred loads in here
     parser_opcode!(data, 0x12);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-    let num_elements = data[1 + pkg_length_len];
-
-    let elements = match parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length]) {
-        Ok(e) => e,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((DefPackage::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
-        Err(e) => return Err(e)
-    };
-
-    Ok((DefPackage::Package {num_elements, elements}, 1 + pkg_length))
+    let numelements = data[1 + pkg_length_len] as usize;
+    let mut elements = parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length], ctx)?.val.get_as_package()?;
+
+    if elements.len() > numelements {
+        elements = elements[0 .. numelements].to_vec();
+    } else if numelements > elements.len() {
+        for _ in 0..numelements - elements.len() {
+            elements.push(AmlValue::Uninitialized);
+        }
+    }
+    
+    Ok(AmlParseType {
+        val: AmlValue::Package(elements),
+        len: 1 + pkg_length
+    })
 }
 
-pub fn parse_def_var_package(data: &[u8]) -> Result<(DefVarPackage, usize), AmlInternalError> {
+pub fn parse_def_var_package(data: &[u8],
+                             ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: Handle deferred loads in here
     parser_opcode!(data, 0x13);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-    let (num_elements, num_elements_len) = parse_term_arg(&data[1 + pkg_length_len ..])?;
-
-    let elements = match parse_package_elements_list(&data[1 + pkg_length_len + num_elements_len ..
-                                                           1 + pkg_length]) {
-        Ok(e) => e,
-        Err(AmlInternalError::AmlDeferredLoad) =>
-            return Ok((DefVarPackage::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
-                       1 + pkg_length)),
-        Err(e) => return Err(e)
-    };
+    let num_elements = parse_term_arg(&data[1 + pkg_length_len .. 1 + pkg_length], ctx)?;
+    let mut elements = parse_package_elements_list(&data[1 + pkg_length_len + num_elements.len ..
+                                                         1 + pkg_length], ctx)?.val.get_as_package()?;
 
-    Ok((DefVarPackage::Package {num_elements, elements}, 1 + pkg_length))
+    let numelements = num_elements.val.get_as_integer()? as usize;
+
+    if elements.len() > numelements {
+        elements = elements[0 .. numelements].to_vec();
+    } else if numelements > elements.len() {
+        for _ in 0..numelements - elements.len() {
+            elements.push(AmlValue::Uninitialized);
+        }
+    }
+    
+    Ok(AmlParseType {
+        val: AmlValue::Package(elements),
+        len: 1 + pkg_length
+    })
 }
 
-fn parse_package_elements_list(data: &[u8]) -> Result<Vec<PackageElement>, AmlInternalError> {
+fn parse_package_elements_list(data: &[u8],
+                               ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     let mut current_offset: usize = 0;
-    let mut elements: Vec<PackageElement> = vec!();
+    let mut elements: Vec<AmlValue> = vec!();
 
     while current_offset < data.len() {
-        match parse_data_ref_obj(&data[current_offset ..]) {
-            Ok((data_ref_obj, data_ref_obj_len)) => {
-                elements.push(PackageElement::DataRefObj(data_ref_obj));
-                current_offset += data_ref_obj_len;
-            },
-            Err(AmlInternalError::AmlInvalidOpCode) =>
-                match parse_name_string(&data[current_offset ..]) {
-                    Ok((name_string, name_string_len)) => {
-                        elements.push(PackageElement::NameString(name_string));
-                        current_offset += name_string_len;
-                    },
-                    Err(e) => return Err(e)
-                },
-            Err(e) => return Err(e)
-        }
+        let dro = if let Ok(e) = parse_data_ref_obj(&data[current_offset..], ctx) {
+            e
+        } else {
+            let d = parse_name_string(&data[current_offset..], ctx)?;
+            AmlParseType {
+                val: AmlValue::ObjectReference(ObjectReference::Object(d.val.get_as_string()?)),
+                len: d.len
+            }
+        };
+
+        elements.push(dro.val);
+        current_offset += dro.len;
     }
 
-    Ok(elements)
+    Ok(AmlParseType {
+        val: AmlValue::Package(elements),
+        len: data.len()
+    })
 }
 
-pub fn parse_def_buffer(data: &[u8]) -> Result<(DefBuffer, usize), AmlInternalError> {
+pub fn parse_def_buffer(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x11);
 
     let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
-    let (buffer_size, buffer_size_len) = match parse_term_arg(&data[1 + pkg_length_len..]) {
-        Ok(s) => s,
-        Err(AmlInternalError::AmlDeferredLoad) => return Ok((DefBuffer::DeferredLoad(
-            data[0 .. 1 + pkg_length].to_vec()
-        ), 1 + pkg_length)),
-        Err(e) => return Err(e),
-    };
-    let byte_list = data[1 + pkg_length_len + buffer_size_len .. 1 + pkg_length].to_vec();
+    let buffer_size = parse_term_arg(&data[1 + pkg_length_len..], ctx)?;
+    let mut byte_list = data[1 + pkg_length_len + buffer_size.len .. 1 + pkg_length].to_vec().clone();
 
-    Ok((DefBuffer::Buffer {buffer_size, byte_list}, pkg_length + 1))
+    byte_list.truncate(buffer_size.val.get_as_integer()? as usize);        
+
+    Ok(AmlParseType {
+        val: AmlValue::Buffer(byte_list),
+        len: 1 + pkg_length
+    })
 }
 
-fn parse_def_ref_of(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+fn parse_def_ref_of(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x71);
-    let (obj_reference, obj_reference_len) = parse_super_name(&data[1..])?;
 
-    Ok((obj_reference, obj_reference_len + 1))
+    let obj = parse_super_name(&data[1..], ctx)?;
+    let res = match obj.val {
+        AmlValue::String(ref s) => {
+            match ctx.get(AmlValue::String(s.clone()))? {
+                AmlValue::None => return Err(AmlError::AmlValueError),
+                _ => ObjectReference::Object(s.clone())
+            }
+        },
+        AmlValue::ObjectReference(ref o) => o.clone(),
+        _ => return Err(AmlError::AmlValueError)
+    };
+    
+    Ok(AmlParseType {
+        val: AmlValue::ObjectReference(res),
+        len: 1 + obj.len
+    })
 }
 
-fn parse_def_deref_of(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> {
+fn parse_def_deref_of(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x83);
-    let (obj_reference, obj_reference_len) = parse_term_arg(&data[1..])?;
 
-    Ok((obj_reference, obj_reference_len + 1))
+    let obj = parse_term_arg(&data[1..], ctx)?;
+    let res = ctx.get(obj.val)?;
+
+    match res {
+        AmlValue::None => Err(AmlError::AmlValueError),
+        _ => Ok(AmlParseType {
+            val: res,
+            len: 1 + obj.len
+        })
+    }
 }
 
-fn parse_def_acquire(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_acquire(data: &[u8],
+                     ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x23);
 
-    let (object, object_len) = parse_super_name(&data[2..])?;
-    let timeout = (data[2 + object_len] as u16) +
-        ((data[3 + object_len] as u16) << 8);
-
-    Ok((Type2OpCode::DefAcquire {object, timeout}, object_len + 4))
+    let obj = parse_super_name(&data[1..], ctx)?;
+    let timeout = (data[2 + obj.len] as u16) + ((data[3 + obj.len] as u16) << 8);
+
+    let (seconds, nanoseconds) = monotonic();
+    let starting_time_ns = nanoseconds + (seconds * 1000000000);
+
+    loop {
+        match ctx.acquire_mutex(obj.val.clone()) {
+            Err(e) => return Err(e),
+            Ok(b) => if b {
+                return Ok(AmlParseType {
+                    val: AmlValue::Integer(0),
+                    len: 4 + obj.len
+                });
+            } else if timeout == 0xFFFF {
+                // TODO: Brief sleep here
+            } else {
+                let (seconds, nanoseconds) = monotonic();
+                let current_time_ns = nanoseconds + (seconds * 1000000000);
+                
+                if current_time_ns - starting_time_ns > timeout as u64 * 1000000 {
+                    return Ok(AmlParseType {
+                        val: AmlValue::Integer(1),
+                        len: 4 + obj.len
+                    });
+                }
+            }
+        }
+    }
 }
 
-fn parse_def_increment(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_increment(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x75);
 
-    let (obj, obj_len) = parse_super_name(&data[1..])?;
-    Ok((Type2OpCode::DefIncrement(obj), obj_len + 1))
+    let obj = parse_super_name(&data[1..], ctx)?;
+    
+    let mut namespace = ctx.prelock();
+    let value = AmlValue::Integer(ctx.get(obj.val.clone())?.get_as_integer()? + 1);
+    ctx.modify(obj.val, value.clone());
+    
+    Ok(AmlParseType {
+        val: value,
+        len: 1 + obj.len
+    })
 }
 
-fn parse_def_index(data: &[u8]) -> Result<(DefIndex, usize), AmlInternalError> {
+fn parse_def_index(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x88);
 
-    let (obj, obj_len) = parse_term_arg(&data[1..])?;
-    let (idx, idx_len) = parse_term_arg(&data[1 + obj_len..])?;
-    let (target, target_len) = parse_target(&data[1 + obj_len + idx_len..])?;
-
-    Ok((DefIndex {obj, idx, target: Box::new(target)}, 1 + obj_len + idx_len + target_len))
+    let obj = parse_term_arg(&data[1..], ctx)?;
+    let idx = parse_term_arg(&data[1 + obj.len..], ctx)?;
+    let target = parse_target(&data[1 + obj.len + idx.len..], ctx)?;
+
+    let reference = AmlValue::ObjectReference(ObjectReference::Index(Box::new(obj.val), Box::new(idx.val)));
+    ctx.modify(target.val, reference.clone());
+    
+    Ok(AmlParseType {
+        val: reference,
+        len: 1 + obj.len + idx.len + target.len
+    })
 }
 
-fn parse_def_land(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_land(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x90);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefLAnd {lhs, rhs}, 1 + lhs_len + rhs_len))
+    let result = if lhs.val.get_as_integer()? > 0 && rhs.val.get_as_integer()? > 0 { 1 } else { 0 };
+    
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(result),
+        len: 1 + lhs.len + rhs.len
+    })
 }
 
-fn parse_def_lequal(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_lequal(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x93);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefLEqual {lhs, rhs}, 1 + lhs_len + rhs_len))
+    let result = if lhs.val.get_as_integer()? == rhs.val.get_as_integer()? { 1 } else { 0 };
+    
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(result),
+        len: 1 + lhs.len + rhs.len
+    })
 }
 
-fn parse_def_lgreater(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_lgreater(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x94);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefLGreater {lhs, rhs}, 1 + lhs_len + rhs_len))
+    let result = if lhs.val.get_as_integer()? > rhs.val.get_as_integer()? { 1 } else { 0 };
+    
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(result),
+        len: 1 + lhs.len + rhs.len
+    })
 }
 
-fn parse_def_lless(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_lless(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x95);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefLLess {lhs, rhs}, 1 + lhs_len + rhs_len))
+    let result = if lhs.val.get_as_integer()? < rhs.val.get_as_integer()? { 1 } else { 0 };
+    
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(result),
+        len: 1 + lhs.len + rhs.len
+    })
 }
 
-fn parse_def_lnot(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_lnot(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x92);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-
-    Ok((Type2OpCode::DefLNot(operand), 1 + operand_len))
+    let operand = parse_term_arg(&data[1..], ctx)?;
+    let result = if operand.val.get_as_integer()? == 0 { 1 } else { 0 };
+    
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(result),
+        len: 1 + operand.len
+    })
 }
 
-fn parse_def_lor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_lor(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x91);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefLOr {lhs, rhs}, 1 + lhs_len + rhs_len))
+    let result = if lhs.val.get_as_integer()? > 0 || rhs.val.get_as_integer()? > 0 { 1 } else { 0 };
+    
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(result),
+        len: 1 + lhs.len + rhs.len
+    })
 }
 
-fn parse_def_to_hex_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_to_hex_string(data: &[u8],
+                           ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x98);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
+
+    let res = match operand.val {
+        AmlValue::Integer(_) => {
+            let result: String = format!("{:X}", operand.val.get_as_integer()?);
+            AmlValue::String(result)
+        },
+        AmlValue::String(s) => AmlValue::String(s),
+        AmlValue::Buffer(_) => {
+            let mut string: String = String::new();
+
+            for b in operand.val.get_as_buffer()? {
+                string.push_str(&format!("{:X}", b));
+            }
+
+            AmlValue::String(string)
+        },
+        _ => return Err(AmlError::AmlValueError)
+    };
+
+    ctx.modify(target.val, res.clone());
 
-    Ok((Type2OpCode::DefToHexString {operand, target}, 1 + operand_len + target_len))
+    Ok(AmlParseType {
+        val: res,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_to_buffer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_to_buffer(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x96);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
 
-    Ok((Type2OpCode::DefToBuffer {operand, target}, 1 + operand_len + target_len))
+    let res = AmlValue::Buffer(operand.val.get_as_buffer()?);
+    ctx.modify(target.val, res.clone());
+
+    Ok(AmlParseType {
+        val: res,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_to_bcd(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_to_bcd(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x29);
 
-    let (operand, operand_len) = parse_term_arg(&data[2..])?;
-    let (target, target_len) = parse_target(&data[2 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
+    
+    let mut i = operand.val.get_as_integer()?;
+    let mut result = 0;
 
-    Ok((Type2OpCode::DefToBCD {operand, target}, 2 + operand_len + target_len))
+    while i != 0 {
+        result <<= 4;
+        result += i % 10;
+        i /= 10;
+    }
+    
+    let result = AmlValue::Integer(result);
+    ctx.modify(target.val, result.clone());
+
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_to_decimal_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_to_decimal_string(data: &[u8],
+                               ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+
     parser_opcode!(data, 0x97);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
+    let res = match operand.val {
+        AmlValue::Integer(_) => {
+            let result: String = format!("{}", operand.val.get_as_integer()?);
+            AmlValue::String(result)
+        },
+        AmlValue::String(s) => AmlValue::String(s),
+        AmlValue::Buffer(_) => {
+            let mut string: String = String::new();
+
+            for b in operand.val.get_as_buffer()? {
+                string.push_str(&format!("{}", b));
+            }
+
+            AmlValue::String(string)
+        },
+        _ => return Err(AmlError::AmlValueError)
+    };
 
-    Ok((Type2OpCode::DefToDecimalString {operand, target}, 1 + operand_len + target_len))
+    ctx.modify(target.val, res.clone());
+
+    Ok(AmlParseType {
+        val: res,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_to_integer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_to_integer(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x99);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
 
-    Ok((Type2OpCode::DefToInteger {operand, target}, 1 + operand_len + target_len))
+    let res = AmlValue::Integer(operand.val.get_as_integer()?);
+
+    ctx.modify(target.val, res.clone());
+
+    Ok(AmlParseType {
+        val: res,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_to_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_to_string(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x9C);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (length, length_len) = parse_term_arg(&data[1 + operand_len..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len + length_len..])?;
+    let operand = parse_term_arg(&data[1..], ctx)?;
+    let length = parse_term_arg(&data[1 + operand.len..], ctx)?;
+    let target = parse_target(&data[1 + operand.len + length.len..], ctx)?;
+
+    let buf = operand.val.get_as_buffer()?;
+    let mut string = match String::from_utf8(buf) {
+        Ok(s) => s,
+        Err(_) => return Err(AmlError::AmlValueError)
+    };
 
-    Ok((Type2OpCode::DefToString {operand, length, target}, 1 + operand_len + length_len + target_len))
+    string.truncate(length.val.get_as_integer()? as usize);
+    let res = AmlValue::String(string);
+
+    ctx.modify(target.val, res.clone());
+
+    Ok(AmlParseType {
+        val: res,
+        len: 1 + operand.len + length.len + target.len
+    })
 }
 
-fn parse_def_subtract(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_subtract(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x74);
 
-    let (minuend, minuend_len) = parse_term_arg(&data[1..])?;
-    let (subtrahend, subtrahend_len) = parse_term_arg(&data[1 + minuend_len..])?;
-    let (target, target_len) = parse_target(&data[1 + minuend_len + subtrahend_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefSubtract {minuend, subtrahend, target}, 1 + minuend_len + subtrahend_len + target_len))
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? - rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_size_of(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_size_of(data: &[u8],
+                     ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x87);
 
-    let (name, name_len) = parse_super_name(&data[1..])?;
-    Ok((Type2OpCode::DefSizeOf(name), name_len + 1))
+    let name = parse_super_name(&data[1..], ctx)?;
+    let obj = ctx.get(name.val)?;
+
+    let res = match obj {
+        AmlValue::Buffer(ref v) => v.len(),
+        AmlValue::String(ref s) => s.len(),
+        AmlValue::Package(ref p) => p.len(),
+        _ => return Err(AmlError::AmlValueError)
+    };
+    
+    Ok(AmlParseType {
+        val: AmlValue::Integer(res as u64),
+        len: 1 + name.len
+    })
 }
 
-fn parse_def_store(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_store(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x70);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_super_name(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[1..], ctx)?;
+    let target = parse_super_name(&data[1 + operand.len..], ctx)?;
 
-    Ok((Type2OpCode::DefStore {operand, target}, operand_len + target_len + 1))
+    ctx.modify(target.val.clone(), operand.val);
+    
+    Ok(AmlParseType {
+        val: target.val,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_or(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_or(data: &[u8],
+                ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x7D);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
-
-    Ok((Type2OpCode::DefOr {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+    
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_shift_left(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_shift_left(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x79);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
-
-    Ok((Type2OpCode::DefShiftLeft {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+    
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_shift_right(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_shift_right(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x7A);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? << rhs.val.get_as_integer()?);
 
-    Ok((Type2OpCode::DefShiftRight {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    ctx.modify(target.val, result.clone());
+                                                              
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_add(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_add(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x72);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
-
-    Ok((Type2OpCode::DefAdd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+    
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? + rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_and(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_and(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x7B);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
-
-    Ok((Type2OpCode::DefAnd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+    
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_xor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_xor(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x7F);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
-
-    Ok((Type2OpCode::DefXor {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+    
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_concat_res(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_concat_res(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x84);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
 
-    Ok((Type2OpCode::DefConcatRes {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
-}
+    let mut buf1 = lhs.val.get_as_buffer()?.clone();
+    let mut buf2 = rhs.val.get_as_buffer()?.clone();
 
-fn parse_def_wait(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    parser_opcode_extended!(data, 0x25);
+    if buf1.len() == 1 || buf2.len() == 1 {
+        return Err(AmlError::AmlValueError);
+    }
+
+    if buf1.len() >= 2 && buf1[buf1.len() - 2] == 0x79 {
+        buf1 = buf1[0..buf1.len() - 2].to_vec();
+    }
+    
+    if buf2.len() >= 2 && buf2[buf2.len() - 2] == 0x79 {
+        buf2 = buf2[0..buf2.len() - 2].to_vec();
+    }
 
-    let (event_object, event_object_len) = parse_super_name(&data[2..])?;
-    let (operand, operand_len) = parse_term_arg(&data[2 + event_object_len..])?;
+    buf1.append(&mut buf2);
+    buf1.push(0x79);
 
+    let mut checksum: u8 = 0;
+    let loopbuf = buf1.clone();
+    for b in loopbuf {
+        checksum += b;
+    }
 
-    Ok((Type2OpCode::DefWait {event_object, operand}, 2 + event_object_len + operand_len))
+    checksum = (!checksum) + 1;
+    buf1.push(checksum);
+    
+    let res = AmlValue::Buffer(buf1);
+    ctx.modify(target.val, res.clone())?;
+    
+    Ok(AmlParseType {
+        val: res,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_cond_ref_of(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_wait(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode_extended!(data, 0x25);
+
+    let obj = parse_super_name(&data[2..], ctx)?;
+    let timeout_obj = parse_term_arg(&data[2 + obj.len..], ctx)?;
+
+    let timeout = timeout_obj.val.get_as_integer()?;
+
+    let (seconds, nanoseconds) = monotonic();
+    let starting_time_ns = nanoseconds + (seconds * 1000000000);
+
+    loop {
+        match ctx.wait_for_event(obj.val.clone()) {
+            Err(e) => return Err(e),
+            Ok(b) => if b {
+                return Ok(AmlParseType {
+                    val: AmlValue::Integer(0),
+                    len: 2 + obj.len + timeout_obj.len
+                })
+            } else if timeout >= 0xFFFF {
+                // TODO: Brief sleep here
+            } else {
+                let (seconds, nanoseconds) = monotonic();
+                let current_time_ns = nanoseconds + (seconds * 1000000000);
+                
+                if current_time_ns - starting_time_ns > timeout as u64 * 1000000 {
+                    return Ok(AmlParseType {
+                        val: AmlValue::Integer(1),
+                        len: 2 + obj.len + timeout_obj.len
+                    });
+                }
+            }
+        }
+    }
+}
+
+fn parse_def_cond_ref_of(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode_extended!(data, 0x12);
 
-    let (operand, operand_len) = parse_super_name(&data[2..])?;
-    let (target, target_len) = parse_target(&data[2 + operand_len..])?;
+    let obj = parse_super_name(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + obj.len..], ctx)?;
+
+    let res = match obj.val {
+        AmlValue::String(ref s) => {
+            match ctx.get(AmlValue::String(s.clone()))? {
+                AmlValue::None => return Ok(AmlParseType {
+                    val: AmlValue::Integer(0),
+                    len: 1 + obj.len + target.len
+                }),
+                _ => ObjectReference::Object(s.clone())
+            }
+        },
+        AmlValue::ObjectReference(ref o) => o.clone(),
+        _ => return Err(AmlError::AmlValueError)
+    };
 
-    Ok((Type2OpCode::DefCondRefOf {operand, target}, 2 + operand_len + target_len))
+    ctx.modify(target.val, AmlValue::ObjectReference(res));
+    
+    Ok(AmlParseType {
+        val: AmlValue::Integer(1),
+        len: 1 + obj.len + target.len
+    })
 }
 
-fn parse_def_copy_object(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_copy_object(data: &[u8],
+                         ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: Compute the result
+    // TODO: Store the result
     parser_opcode!(data, 0x9D);
 
-    let (source, source_len) = parse_term_arg(&data[1..])?;
-    let (destination, destination_len) = parse_simple_name(&data[1 + source_len..])?;
+    let source = parse_term_arg(&data[1..], ctx)?;
+    let destination = parse_simple_name(&data[1 + source.len..], ctx)?;
+
+    ctx.copy(destination.val, source.val.clone())?;
 
-    Ok((Type2OpCode::DefCopyObject {source, destination}, 1 + source_len + destination_len))
+    Ok(AmlParseType {
+        val: source.val,
+        len: 1 + source.len + destination.len
+    })
 }
 
-fn parse_def_concat(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_concat(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x73);
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+
+    let result = match lhs.val {
+        AmlValue::Integer(i) => {
+            let j = AmlValue::Integer(rhs.val.get_as_integer()?);
+
+            let mut first = lhs.val.get_as_buffer()?.clone();
+            let mut second = j.get_as_buffer()?.clone();
+
+            first.append(&mut second);
+
+            AmlValue::Buffer(first)
+        },
+        AmlValue::String(s) => {
+            let t = if let Ok(t) = rhs.val.get_as_string() {
+                t
+            } else {
+                rhs.val.get_type_string()
+            };
+
+            AmlValue::String(format!("{}{}", s, t))
+        },
+        AmlValue::Buffer(b) => {
+            let mut b = b.clone();
+            let mut c = if let Ok(c) = rhs.val.get_as_buffer() {
+                c.clone()
+            } else {
+                AmlValue::String(rhs.val.get_type_string()).get_as_buffer()?.clone()
+            };
+
+            b.append(&mut c);
+
+            AmlValue::Buffer(b)
+        },
+        _ => {
+            let first = lhs.val.get_type_string();
+            let second = if let Ok(second) = rhs.val.get_as_string() {
+                second
+            } else {
+                rhs.val.get_type_string()
+            };
+
+            AmlValue::String(format!("{}{}", first, second))
+        }
+    };
+
+    ctx.modify(target.val, result.clone())?;
 
-    Ok((Type2OpCode::DefConcat {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_decrement(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_decrement(data: &[u8],
+                       ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x76);
 
-    let (target, target_len) = parse_super_name(&data[1..])?;
-
-    Ok((Type2OpCode::DefDecrement(target), 1 + target_len))
+    let obj = parse_super_name(&data[1..], ctx)?;
+    
+    let mut namespace = ctx.prelock();
+    let value = AmlValue::Integer(ctx.get(obj.val.clone())?.get_as_integer()? - 1);
+    ctx.modify(obj.val, value.clone());
+    
+    Ok(AmlParseType {
+        val: value,
+        len: 1 + obj.len
+    })
 }
 
-fn parse_def_divide(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_divide(data: &[u8],
+                    ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x78);
 
-    let (dividend, dividend_len) = parse_term_arg(&data[1..])?;
-    let (divisor, divisor_len) = parse_term_arg(&data[1 + dividend_len..])?;
-    let (remainder, remainder_len) = parse_target(&data[1 + dividend_len + divisor_len..])?;
-    let (quotient, quotient_len) = parse_target(&data[1 + dividend_len + divisor_len + remainder_len..])?;
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target_remainder = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+    let target_quotient = parse_target(&data[1 + lhs.len + rhs.len + target_remainder.len..], ctx)?;
+
+    let numerator = lhs.val.get_as_integer()?;
+    let denominator = rhs.val.get_as_integer()?;
+
+    let remainder = numerator % denominator;
+    let quotient = (numerator - remainder) / denominator;
 
-    Ok((Type2OpCode::DefDivide {dividend, divisor, remainder, quotient},
-        1 + dividend_len + divisor_len + remainder_len + quotient_len))
+    ctx.modify(target_remainder.val, AmlValue::Integer(remainder));
+    ctx.modify(target_quotient.val, AmlValue::Integer(quotient));
+    
+    Ok(AmlParseType {
+        val: AmlValue::Integer(quotient),
+        len: 1 + lhs.len + rhs.len + target_remainder.len + target_quotient.len
+    })
 }
 
-fn parse_def_find_set_left_bit(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+fn parse_def_find_set_left_bit(data: &[u8],
+                               ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
     parser_opcode!(data, 0x81);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
 
-    Ok((Type2OpCode::DefFindSetLeftBit {operand, target}, 1 + operand_len + target_len))
-}
+    let mut first_bit = 32;
+    let mut test = operand.val.get_as_integer()?;
+    
+    while first_bit > 0{
+        if test & 0x8000000000000000 > 0 {
+            break;
+        }
 
-fn parse_def_find_set_right_bit(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x82 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+        test <<= 1;
+        first_bit -= 1;
     }
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
-
-    Ok((Type2OpCode::DefFindSetRightBit {operand, target}, 1 + operand_len + target_len))
+    let result = AmlValue::Integer(first_bit);
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_load_table(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x1F {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_find_set_right_bit(data: &[u8],
+                                ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x82);
+
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
+
+    let mut first_bit = 1;
+    let mut test = operand.val.get_as_integer()?;
+    
+    while first_bit <= 32 {
+        if test & 1 > 0 {
+            break;
+        }
 
-    let (signature, signature_len) = parse_term_arg(&data[2..])?;
-    let (oem_id, oem_id_len) = parse_term_arg(&data[2 + signature_len..])?;
-    let (oem_table_id, oem_table_id_len) = parse_term_arg(&data[2 + signature_len + oem_id_len..])?;
-    let (root_path, root_path_len) =
-        parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len..])?;
-    let (parameter_path, parameter_path_len) =
-        parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len + root_path_len..])?;
-    let (parameter_data, parameter_data_len) =
-        parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len + root_path_len +
-                             parameter_path_len..])?;
+        test >>= 1;
+        first_bit += 1;
+    }
 
-    Ok((Type2OpCode::DefLoadTable {signature, oem_id, oem_table_id, root_path,
-                                   parameter_path, parameter_data},
-        2 + signature_len + oem_id_len + oem_table_id_len + root_path_len +
-        parameter_path_len + parameter_data_len))
+    if first_bit == 33 {
+        first_bit = 0;
+    }
+
+    let result = AmlValue::Integer(first_bit);
+    ctx.modify(target.val, result.clone());
+
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_match(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x89 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_load_table(data: &[u8],
+                        ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    // TODO: Clean up
+    parser_opcode_extended!(data, 0x1F);
+
+    let signature = parse_term_arg(&data[2..], ctx)?;
+    let oem_id = parse_term_arg(&data[2 + signature.len..], ctx)?;
+    let oem_table_id = parse_term_arg(&data[2 + signature.len + oem_id.len..], ctx)?;
+    let root_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len..], ctx)?;
+    let parameter_path = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len..], ctx)?;
+    let parameter_data = parse_term_arg(&data[2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len..], ctx)?;
+
+    if let Some(ref ptrs) = *(SDT_POINTERS.read()) {
+        let sig_str = unsafe {
+            let sig = *(signature.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 4]);
+            String::from_utf8(sig.to_vec()).expect("Error converting signature to string")
+        };
+        let oem_str = unsafe {
+            *(oem_id.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 6])
+        };
+        let oem_table_str = unsafe {
+            *(oem_table_id.val.get_as_string()?.as_bytes().as_ptr() as *const [u8; 8])
+        };
+
+        let sdt_signature = (sig_str, oem_str, oem_table_str);
+        
+        let sdt = ptrs.get(&sdt_signature);
+        
+        if let Some(sdt) = sdt {
+            let hdl = parse_aml_with_scope(sdt, root_path.val.get_as_string()?)?;
+            ctx.modify(parameter_path.val, parameter_data.val);
+            
+            return Ok(AmlParseType {
+                val: AmlValue::DDBHandle((hdl, sdt_signature)),
+                len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len
+            });
+        }
     }
 
-    let (search_pkg, search_pkg_len) = parse_term_arg(&data[1..])?;
-    let first_operation = match data[1 + search_pkg_len] {
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(0),
+        len: 2 + signature.len + oem_id.len + oem_table_id.len + root_path.len + parameter_path.len + parameter_data.len
+    })
+}
+
+fn parse_def_match(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode!(data, 0x28);
+    
+    let search_pkg = parse_term_arg(&data[1..], ctx)?;
+    
+    let first_operation = match data[1 + search_pkg.len] {
         0 => MatchOpcode::MTR,
         1 => MatchOpcode::MEQ,
         2 => MatchOpcode::MLE,
         3 => MatchOpcode::MLT,
         4 => MatchOpcode::MGE,
         5 => MatchOpcode::MGT,
-        _ => return Err(AmlInternalError::AmlParseError("DefMatch - Invalid Opcode"))
+        _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode"))
     };
-    let (first_operand, first_operand_len) = parse_term_arg(&data[2 + search_pkg_len..])?;
+    let first_operand = parse_term_arg(&data[2 + search_pkg.len..], ctx)?;
 
-    let second_operation = match data[2 + search_pkg_len + first_operand_len] {
+    let second_operation = match data[2 + search_pkg.len + first_operand.len] {
         0 => MatchOpcode::MTR,
         1 => MatchOpcode::MEQ,
         2 => MatchOpcode::MLE,
         3 => MatchOpcode::MLT,
         4 => MatchOpcode::MGE,
         5 => MatchOpcode::MGT,
-        _ => return Err(AmlInternalError::AmlParseError("DefMatch - Invalid Opcode"))
+        _ => return Err(AmlError::AmlParseError("DefMatch - Invalid Opcode"))
     };
-    let (second_operand, second_operand_len) =
-        parse_term_arg(&data[3 + search_pkg_len + first_operand_len..])?;
+    let second_operand = parse_term_arg(&data[3 + search_pkg.len + first_operand.len..], ctx)?;
+    
+    let start_index = parse_term_arg(&data[3 + search_pkg.len + first_operand.len + second_operand.len..], ctx)?;
+
+    let pkg = search_pkg.val.get_as_package()?;
+    let mut idx = start_index.val.get_as_integer()? as usize;
+
+    match first_operand.val {
+        AmlValue::Integer(i) => {
+            let j = second_operand.val.get_as_integer()?;
+
+            while idx < pkg.len() {
+                let val = if let Ok(v) = pkg[idx].get_as_integer() { v } else { idx += 1; continue; };
+                idx += 1;
+
+                match first_operation {
+                    MatchOpcode::MTR => (),
+                    MatchOpcode::MEQ => if val != i { continue },
+                    MatchOpcode::MLE => if val > i { continue },
+                    MatchOpcode::MLT => if val >= i { continue },
+                    MatchOpcode::MGE => if val < i { continue },
+                    MatchOpcode::MGT => if val <= i { continue }
+                }
+
+                match second_operation {
+                    MatchOpcode::MTR => (),
+                    MatchOpcode::MEQ => if val != j { continue },
+                    MatchOpcode::MLE => if val > j { continue },
+                    MatchOpcode::MLT => if val >= j { continue },
+                    MatchOpcode::MGE => if val < j { continue },
+                    MatchOpcode::MGT => if val <= j { continue }
+                }
+
+                return Ok(AmlParseType {
+                    val: AmlValue::Integer(idx as u64),
+                    len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
+                })
+            }
+        },
+        AmlValue::String(i) => {
+            let j = second_operand.val.get_as_string()?;
+
+            while idx < pkg.len() {
+                let val = if let Ok(v) = pkg[idx].get_as_string() { v } else { idx += 1; continue; };
+                idx += 1;
+
+                match first_operation {
+                    MatchOpcode::MTR => (),
+                    MatchOpcode::MEQ => if val != i { continue },
+                    MatchOpcode::MLE => if val > i { continue },
+                    MatchOpcode::MLT => if val >= i { continue },
+                    MatchOpcode::MGE => if val < i { continue },
+                    MatchOpcode::MGT => if val <= i { continue }
+                }
+
+                match second_operation {
+                    MatchOpcode::MTR => (),
+                    MatchOpcode::MEQ => if val != j { continue },
+                    MatchOpcode::MLE => if val > j { continue },
+                    MatchOpcode::MLT => if val >= j { continue },
+                    MatchOpcode::MGE => if val < j { continue },
+                    MatchOpcode::MGT => if val <= j { continue }
+                }
+
+                return Ok(AmlParseType {
+                    val: AmlValue::Integer(idx as u64),
+                    len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
+                })
+            }
+        },
+        _ => {
+            let i = first_operand.val.get_as_buffer()?;
+            let j = second_operand.val.get_as_buffer()?;
+
+            while idx < pkg.len() {
+                let val = if let Ok(v) = pkg[idx].get_as_buffer() { v } else { idx += 1; continue; };
+                idx += 1;
+
+                match first_operation {
+                    MatchOpcode::MTR => (),
+                    MatchOpcode::MEQ => if val != i { continue },
+                    MatchOpcode::MLE => if val > i { continue },
+                    MatchOpcode::MLT => if val >= i { continue },
+                    MatchOpcode::MGE => if val < i { continue },
+                    MatchOpcode::MGT => if val <= i { continue }
+                }
+
+                match second_operation {
+                    MatchOpcode::MTR => (),
+                    MatchOpcode::MEQ => if val != j { continue },
+                    MatchOpcode::MLE => if val > j { continue },
+                    MatchOpcode::MLT => if val >= j { continue },
+                    MatchOpcode::MGE => if val < j { continue },
+                    MatchOpcode::MGT => if val <= j { continue }
+                }
 
-    let (start_index, start_index_len) =
-        parse_term_arg(&data[3 + search_pkg_len + first_operand_len + second_operand_len..])?;
+                return Ok(AmlParseType {
+                    val: AmlValue::Integer(idx as u64),
+                    len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
+                })
+            }
+        }
+    }
 
-    Ok((Type2OpCode::DefMatch {search_pkg, first_operation, first_operand,
-                               second_operation, second_operand, start_index},
-        3 + search_pkg_len + first_operand_len + second_operand_len + start_index_len))
+    Ok(AmlParseType {
+        val: AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF),
+        len: 3 + search_pkg.len + first_operand.len + second_operand.len + start_index.len
+    })
 }
 
-fn parse_def_from_bcd(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x28 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_from_bcd(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode_extended!(data, 0x28);
 
-    let (operand, operand_len) = parse_term_arg(&data[2..])?;
-    let (target, target_len) = parse_target(&data[2 + operand_len..])?;
+    let operand = parse_term_arg(&data[2..], ctx)?;
+    let target = parse_target(&data[2 + operand.len..], ctx)?;
 
-    Ok((Type2OpCode::DefFromBCD {operand, target}, 2 + operand_len + target_len))
-}
+    let mut i = operand.val.get_as_integer()?;
+    let mut result = 0;
 
-fn parse_def_mid(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x9E {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+    while i != 0 {
+        if i & 0x0F > 10 {
+            return Err(AmlError::AmlValueError);
+        }
+        
+        result *= 10;
+        result += i & 0x0F;
+        i >>= 4;
     }
 
-    let (source, source_len) = parse_term_arg(&data[1..])?;
-    let (index, index_len) = parse_term_arg(&data[1 + source_len..])?;
-    let (length, length_len) = parse_term_arg(&data[1 + source_len + index_len..])?;
-    let (target, target_len) = parse_target(&data[1 + source_len + index_len + length_len..])?;
+    let result = AmlValue::Integer(result);
 
-    Ok((Type2OpCode::DefMid {source, index, length, target},
-        1 + source_len + index_len + length_len + target_len))
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 2 + operand.len + target.len
+    })
 }
 
-fn parse_def_mod(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x85 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_mid(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x9E);
+
+    let source = parse_term_arg(&data[1..], ctx)?;
+    let index = parse_term_arg(&data[1 + source.len..], ctx)?;
+    let length = parse_term_arg(&data[1 + source.len + index.len..], ctx)?;
+    let target = parse_target(&data[1 + source.len + index.len + length.len..], ctx)?;
+
+    let idx = index.val.get_as_integer()? as usize;
+    let mut len = length.val.get_as_integer()? as usize;
+    
+    let result = match source.val {
+        AmlValue::String(s) => {
+            if idx > s.len() {
+                AmlValue::String(String::new())
+            } else {
+                let mut res = s.clone().split_off(idx);
+
+                if len < res.len() {
+                    res.split_off(len);
+                }
 
-    let (dividend, dividend_len) = parse_term_arg(&data[1..])?;
-    let (divisor, divisor_len) = parse_term_arg(&data[1 + dividend_len..])?;
-    let (target, target_len) = parse_target(&data[1 + dividend_len + divisor_len..])?;
+                AmlValue::String(res)
+            }
+        },
+        _ => {
+            // If it isn't a string already, treat it as a buffer. Must perform that check first,
+            // as Mid can operate on both strings and buffers, but a string can be cast as a buffer
+            // implicitly.
+            // Additionally, any type that can be converted to a buffer can also be converted to a
+            // string, so no information is lost
+            let b = source.val.get_as_buffer()?;
+            
+            if idx > b.len() {
+                AmlValue::Buffer(vec!())
+            } else {
+                if idx + len > b.len() {
+                    len = b.len() - idx;
+                }
+
+                AmlValue::Buffer(b[idx .. idx + len].to_vec())
+            }
+        }
+    };
+    
+    ctx.modify(target.val, result.clone());
 
-    Ok((Type2OpCode::DefMod {dividend, divisor, target}, 1 + dividend_len + divisor_len + target_len))
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + source.len + index.len + length.len + target.len
+    })
 }
 
-fn parse_def_multiply(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x77 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_mod(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode!(data, 0x85);
+
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+
+    if rhs.val.get_as_integer()? == 0 {
+        return Err(AmlError::AmlValueError);
     }
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? % rhs.val.get_as_integer()?);
 
-    Ok((Type2OpCode::DefMultiply {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_nand(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x7C {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_multiply(data: &[u8],
+                      ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    // TODO: Handle overflow
+    parser_opcode!(data, 0x77);
+
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+
+    let result = AmlValue::Integer(lhs.val.get_as_integer()? * rhs.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
+}
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+fn parse_def_nand(data: &[u8],
+                  ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
+    }
+    
+    parser_opcode!(data, 0x7C);
 
-    Ok((Type2OpCode::DefNAnd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
+
+    let result = AmlValue::Integer(!(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?));
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_nor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x7E {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_nor(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x7E);
+
+    let lhs = parse_term_arg(&data[1..], ctx)?;
+    let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
+    let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
 
-    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
-    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
-    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+    let result = AmlValue::Integer(!(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?));
 
-    Ok((Type2OpCode::DefNOr {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + lhs.len + rhs.len + target.len
+    })
 }
 
-fn parse_def_not(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x80 {
-        return Err(AmlInternalError::AmlInvalidOpCode);
+fn parse_def_not(data: &[u8],
+                 ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
+    
+    parser_opcode!(data, 0x80);
 
-    let (operand, operand_len) = parse_term_arg(&data[1..])?;
-    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+    let operand = parse_term_arg(&data[1..], ctx)?;
+    let target = parse_target(&data[1 + operand.len..], ctx)?;
 
-    Ok((Type2OpCode::DefNot {operand, target}, 1 + operand_len + target_len))
+    let result = AmlValue::Integer(!operand.val.get_as_integer()?);
+
+    ctx.modify(target.val, result.clone());
+    
+    Ok(AmlParseType {
+        val: result,
+        len: 1 + operand.len + target.len
+    })
 }
 
-fn parse_def_timer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
-    if data[0] != 0x5B || data[1] != 0x33 {
-        return Err(AmlInternalError::AmlInvalidOpCode)
+fn parse_def_timer(data: &[u8],
+                   ctx: &mut AmlExecutionContext) -> ParseResult {
+    match ctx.state {
+        ExecutionState::EXECUTING => (),
+        _ => return Ok(AmlParseType {
+            val: AmlValue::None,
+            len: 0 as usize
+        })
     }
-
-    Ok((Type2OpCode::DefTimer, 2 as usize))
+    
+    parser_opcode_extended!(data, 0x33);
+
+    let (seconds, nanoseconds) = monotonic();
+    let monotonic_ns = nanoseconds + (seconds * 1000000000);
+    
+    Ok(AmlParseType {
+        val: AmlValue::Integer(monotonic_ns),
+        len: 2 as usize
+    })
 }
diff --git a/src/acpi/dmar/mod.rs b/src/acpi/dmar/mod.rs
index 02aac83d5b59ba18b84a7738ed967c15cb47d7a4..549f6869eab707c8993a7221ab38d0b7fddc9fee 100644
--- a/src/acpi/dmar/mod.rs
+++ b/src/acpi/dmar/mod.rs
@@ -5,6 +5,8 @@ use self::drhd::Drhd;
 use memory::Frame;
 use paging::{entry, ActivePageTable, PhysicalAddress};
 
+use super::{ACPI_TABLE, SDT_POINTERS, get_sdt, find_sdt, load_table, get_sdt_signature};
+
 pub mod drhd;
 
 /// The DMA Remapping Table
@@ -17,6 +19,38 @@ pub struct Dmar {
 }
 
 impl Dmar {
+    pub fn init(active_table: &mut ActivePageTable) {
+        let dmar_sdt = find_sdt("DMAR");
+        let dmar = if dmar_sdt.len() == 1 {
+            load_table(get_sdt_signature(dmar_sdt[0]));
+            Dmar::new(dmar_sdt[0])
+        } else {
+            println!("Unable to find DMAR");
+            return;
+        };
+        
+        if let Some(dmar) = dmar {
+            println!("  DMAR: {}: {}", dmar.addr_width, dmar.flags);
+
+            for dmar_entry in dmar.iter() {
+                println!("      {:?}", dmar_entry);
+                match dmar_entry {
+                    DmarEntry::Drhd(dmar_drhd) => {
+                        let drhd = dmar_drhd.get(active_table);
+
+                        println!("VER: {:X}", drhd.version);
+                        println!("CAP: {:X}", drhd.cap);
+                        println!("EXT_CAP: {:X}", drhd.ext_cap);
+                        println!("GCMD: {:X}", drhd.gl_cmd);
+                        println!("GSTS: {:X}", drhd.gl_sts);
+                        println!("RT: {:X}", drhd.root_table);
+                    },
+                    _ => ()
+                }
+            }
+        }
+    }
+        
     pub fn new(sdt: &'static Sdt) -> Option<Dmar> {
         if &sdt.signature == b"DMAR" && sdt.data_len() >= 12 { //Not valid if no local address and flags
             let addr_width = unsafe { *(sdt.data_address() as *const u8) };
diff --git a/src/acpi/fadt.rs b/src/acpi/fadt.rs
index d40d5a1fc520906a83417c72f73818a7d5f72066..6dd82d867c3bee41e647900226992d2d09a7547e 100644
--- a/src/acpi/fadt.rs
+++ b/src/acpi/fadt.rs
@@ -1,6 +1,10 @@
 use core::{mem, ptr};
+use collections::string::String;
 
 use super::sdt::Sdt;
+use super::{ACPI_TABLE, SDT_POINTERS, get_sdt, find_sdt, get_sdt_signature, load_table};
+
+use paging::ActivePageTable;
 
 #[repr(packed)]
 #[derive(Debug)]
@@ -93,4 +97,29 @@ impl Fadt {
             None
         }
     }
+    
+    pub fn init(active_table: &mut ActivePageTable) {
+        let fadt_sdt = find_sdt("FACP");
+        let fadt = if fadt_sdt.len() == 1 {
+            load_table(get_sdt_signature(fadt_sdt[0]));
+            Fadt::new(fadt_sdt[0])
+        } else {
+            println!("Unable to find FADT");
+            return;
+        };
+
+        if let Some(fadt) = fadt {
+            println!("  FACP: {:X}", fadt.dsdt);
+            
+            let dsdt_sdt = get_sdt(fadt.dsdt as usize, active_table);
+
+            let signature = get_sdt_signature(dsdt_sdt);
+            if let Some(ref mut ptrs) = *(SDT_POINTERS.write()) {
+                ptrs.insert(signature, dsdt_sdt);
+            }
+
+            let mut fadt_t = ACPI_TABLE.fadt.write();
+            *fadt_t = Some(fadt);
+        }
+    }
 }
diff --git a/src/acpi/hpet.rs b/src/acpi/hpet.rs
index 664b6bb8d69cd8b32a4ee0770ec4f1ef7fefed71..d2e5ecfbde2cc3d7a45ceba2581947a07f2cd07f 100644
--- a/src/acpi/hpet.rs
+++ b/src/acpi/hpet.rs
@@ -1,6 +1,12 @@
 use core::{mem, ptr};
 
+use core::intrinsics::{volatile_load, volatile_store};
+
+use memory::Frame;
+use paging::{entry, ActivePageTable, PhysicalAddress, Page, VirtualAddress};
+
 use super::sdt::Sdt;
+use super::{ACPI_TABLE, SDT_POINTERS, get_sdt, find_sdt, load_table, get_sdt_signature};
 
 #[repr(packed)]
 #[derive(Clone, Copy, Debug, Default)]
@@ -29,11 +35,48 @@ pub struct Hpet {
 }
 
 impl Hpet {
-    pub fn new(sdt: &'static Sdt) -> Option<Hpet> {
+    pub fn init(active_table: &mut ActivePageTable) {
+        let hpet_sdt = find_sdt("HPET");
+        let hpet = if hpet_sdt.len() == 1 {
+            load_table(get_sdt_signature(hpet_sdt[0]));
+            Hpet::new(hpet_sdt[0], active_table)
+        } else {
+            println!("Unable to find HPET");
+            return;
+        };
+        
+        if let Some(hpet) = hpet {
+            println!("  HPET: {:X}", hpet.hpet_number);
+            
+            let mut hpet_t = ACPI_TABLE.hpet.write();
+            *hpet_t = Some(hpet);
+        }
+    }
+    
+    pub fn new(sdt: &'static Sdt, active_table: &mut ActivePageTable) -> Option<Hpet> {
         if &sdt.signature == b"HPET" && sdt.length as usize >= mem::size_of::<Hpet>() {
-            Some(unsafe { ptr::read((sdt as *const Sdt) as *const Hpet) })
+            let s = unsafe { ptr::read((sdt as *const Sdt) as *const Hpet) };
+            unsafe { s.base_address.init(active_table) };
+            Some(s)
         } else {
             None
         }
     }
 }
+
+impl GenericAddressStructure {
+    pub unsafe fn init(&self, active_table: &mut ActivePageTable) {
+        let page = Page::containing_address(VirtualAddress::new(self.address as usize));
+        let frame = Frame::containing_address(PhysicalAddress::new(self.address as usize));
+        let result = active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
+        result.flush(active_table);
+    }
+    
+    pub unsafe fn read_u64(&self, offset: usize) -> u64{
+        volatile_load((self.address as usize + offset) as *const u64)
+    }
+
+    pub unsafe fn write_u64(&mut self, offset: usize, value: u64) {
+        volatile_store((self.address as usize + offset) as *mut u64, value);
+    }
+}
diff --git a/src/acpi/madt.rs b/src/acpi/madt.rs
index dac16dc7faf66af5c7e0d9d8ce744d621f58f7f1..c4f922a5a12be83c21f8b05356c4840c02e2422e 100644
--- a/src/acpi/madt.rs
+++ b/src/acpi/madt.rs
@@ -1,6 +1,27 @@
 use core::mem;
 
+use memory::{allocate_frames, Frame};
+use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
+
 use super::sdt::Sdt;
+use super::{ACPI_TABLE, SDT_POINTERS, AP_STARTUP, TRAMPOLINE, find_sdt, load_table, get_sdt_signature};
+
+use core::intrinsics::{atomic_load, atomic_store};
+use core::sync::atomic::Ordering;
+use collections::btree_map::BTreeMap;
+use collections::string::String;
+use collections::vec::Vec;
+use alloc::boxed::Box;
+
+use syscall::io::{Io, Pio};
+
+use spin::RwLock;
+
+use stop::kstop;
+
+use device::local_apic::LOCAL_APIC;
+use interrupt;
+use start::{kstart_ap, CPU_COUNT, AP_READY};
 
 /// The Multiple APIC Descriptor Table
 #[derive(Debug)]
@@ -11,6 +32,123 @@ pub struct Madt {
 }
 
 impl Madt {
+    pub fn init(active_table: &mut ActivePageTable) {
+        let madt_sdt = find_sdt("APIC");
+        let madt = if madt_sdt.len() == 1 {
+            load_table(get_sdt_signature(madt_sdt[0]));
+            Madt::new(madt_sdt[0])
+        } else {
+            println!("Unable to find MADT");
+            return;
+        };
+        
+        if let Some(madt) = madt {
+            println!("  APIC: {:>08X}: {}", madt.local_address, madt.flags);
+
+            let local_apic = unsafe { &mut LOCAL_APIC };
+            let me = local_apic.id() as u8;
+
+            if local_apic.x2 {
+                println!("    X2APIC {}", me);
+            } else {
+                println!("    XAPIC {}: {:>08X}", me, local_apic.address);
+            }
+
+            if cfg!(feature = "multi_core"){
+                let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE));
+                let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
+
+                // Map trampoline
+                let result = active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
+                result.flush(active_table);
+
+                for madt_entry in madt.iter() {
+                    println!("      {:?}", madt_entry);
+                    match madt_entry {
+                        MadtEntry::LocalApic(ap_local_apic) => if ap_local_apic.id == me {
+                            println!("        This is my local APIC");
+                        } else {
+                            if ap_local_apic.flags & 1 == 1 {
+                                // Increase CPU ID
+                                CPU_COUNT.fetch_add(1, Ordering::SeqCst);
+
+                                // Allocate a stack
+                                let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET;
+                                let stack_end = stack_start + 64 * 4096;
+
+                                let ap_ready = TRAMPOLINE as *mut u64;
+                                let ap_cpu_id = unsafe { ap_ready.offset(1) };
+                                let ap_page_table = unsafe { ap_ready.offset(2) };
+                                let ap_stack_start = unsafe { ap_ready.offset(3) };
+                                let ap_stack_end = unsafe { ap_ready.offset(4) };
+                                let ap_code = unsafe { ap_ready.offset(5) };
+
+                                // Set the ap_ready to 0, volatile
+                                unsafe { atomic_store(ap_ready, 0) };
+                                unsafe { atomic_store(ap_cpu_id, ap_local_apic.id as u64) };
+                                unsafe { atomic_store(ap_page_table, active_table.address() as u64) };
+                                unsafe { atomic_store(ap_stack_start, stack_start as u64) };
+                                unsafe { atomic_store(ap_stack_end, stack_end as u64) };
+                                unsafe { atomic_store(ap_code, kstart_ap as u64) };
+                                AP_READY.store(false, Ordering::SeqCst);
+
+                                print!("        AP {}:", ap_local_apic.id);
+
+                                // Send INIT IPI
+                                {
+                                    let mut icr = 0x4500;
+                                    if local_apic.x2 {
+                                        icr |= (ap_local_apic.id as u64) << 32;
+                                    } else {
+                                        icr |= (ap_local_apic.id as u64) << 56;
+                                    }
+                                    print!(" IPI...");
+                                    local_apic.set_icr(icr);
+                                }
+
+                                // Send START IPI
+                                {
+                                    //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
+                                    let ap_segment = (AP_STARTUP >> 12) & 0xFF;
+                                    let mut icr = 0x4600 | ap_segment as u64;
+
+                                    if local_apic.x2 {
+                                        icr |= (ap_local_apic.id as u64) << 32;
+                                    } else {
+                                        icr |= (ap_local_apic.id as u64) << 56;
+                                    }
+
+                                    print!(" SIPI...");
+                                    local_apic.set_icr(icr);
+                                }
+
+                                // Wait for trampoline ready
+                                print!(" Wait...");
+                                while unsafe { atomic_load(ap_ready) } == 0 {
+                                    interrupt::pause();
+                                }
+                                print!(" Trampoline...");
+                                while ! AP_READY.load(Ordering::SeqCst) {
+                                    interrupt::pause();
+                                }
+                                println!(" Ready");
+
+                                active_table.flush_all();
+                            } else {
+                                println!("        CPU Disabled");
+                            }
+                        },
+                        _ => ()
+                    }
+                }
+
+                // Unmap trampoline
+                let (result, _frame) = active_table.unmap_return(trampoline_page, false);
+                result.flush(active_table);
+            }
+        }
+    }
+    
     pub fn new(sdt: &'static Sdt) -> Option<Madt> {
         if &sdt.signature == b"APIC" && sdt.data_len() >= 8 { //Not valid if no local address and flags
             let local_address = unsafe { *(sdt.data_address() as *const u32) };
diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs
index f2791169c6cbfee2c5158e071f1618538b2286fc..8324f8e03526bdef0a9be818097e28320caea9bd 100644
--- a/src/acpi/mod.rs
+++ b/src/acpi/mod.rs
@@ -3,8 +3,16 @@
 
 use core::intrinsics::{atomic_load, atomic_store};
 use core::sync::atomic::Ordering;
+use collections::btree_map::BTreeMap;
+use collections::string::String;
+use collections::vec::Vec;
+use alloc::boxed::Box;
 
-use spin::Mutex;
+use syscall::io::{Io, Pio};
+
+use spin::RwLock;
+
+use stop::kstop;
 
 use device::local_apic::LOCAL_APIC;
 use interrupt;
@@ -19,8 +27,10 @@ use self::rsdt::Rsdt;
 use self::sdt::Sdt;
 use self::xsdt::Xsdt;
 use self::hpet::Hpet;
+use self::rxsdt::Rxsdt;
+use self::rsdp::RSDP;
 
-use self::aml::{is_aml_table, parse_aml_table, AmlNamespace, AmlError};
+use self::aml::{is_aml_table, parse_aml_table, AmlError, AmlValue};
 
 pub mod hpet;
 mod dmar;
@@ -30,6 +40,8 @@ mod rsdt;
 mod sdt;
 mod xsdt;
 mod aml;
+mod rxsdt;
+mod rsdp;
 
 const TRAMPOLINE: usize = 0x7E00;
 const AP_STARTUP: usize = TRAMPOLINE + 512;
@@ -62,256 +74,196 @@ fn get_sdt(sdt_address: usize, active_table: &mut ActivePageTable) -> &'static S
     sdt
 }
 
-fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
-    print!("  ");
-    for &c in sdt.signature.iter() {
-        print!("{}", c as char);
-    }
-
-    if let Some(fadt) = Fadt::new(sdt) {
-        println!(": {:X}", fadt.dsdt);
-        let dsdt = get_sdt(fadt.dsdt as usize, active_table);
-        parse_sdt(dsdt, active_table);
-        ACPI_TABLE.lock().fadt = Some(fadt);
-    } else if let Some(madt) = Madt::new(sdt) {
-        println!(": {:>08X}: {}", madt.local_address, madt.flags);
-
-        let local_apic = unsafe { &mut LOCAL_APIC };
-
-        let me = local_apic.id() as u8;
-
-        if local_apic.x2 {
-            println!("    X2APIC {}", me);
-        } else {
-            println!("    XAPIC {}: {:>08X}", me, local_apic.address);
+fn init_aml_table(sdt: &'static Sdt) {
+    match parse_aml_table(sdt) {
+        Ok(_) => println!(": Parsed"),
+        Err(AmlError::AmlParseError(e)) => println!(": {}", e),
+        Err(AmlError::AmlInvalidOpCode) => println!(": Invalid opcode"),
+        Err(AmlError::AmlValueError) => println!(": Type constraints or value bounds not met"),
+        Err(AmlError::AmlDeferredLoad) => println!(": Deferred load reached top level"),
+        Err(AmlError::AmlFatalError(_, _, _)) => {
+            println!(": Fatal error occurred");
+            unsafe { kstop(); }
+        },
+        Err(AmlError::AmlHardFatal) => {
+            println!(": Fatal error occurred");
+            unsafe { kstop(); }
         }
+    }
+}
 
-        if cfg!(feature = "multi_core"){
-            let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE));
-            let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
-
-            // Map trampoline
-            let result = active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
-            result.flush(active_table);
-
-            for madt_entry in madt.iter() {
-                println!("      {:?}", madt_entry);
-                match madt_entry {
-                    MadtEntry::LocalApic(ap_local_apic) => if ap_local_apic.id == me {
-                        println!("        This is my local APIC");
-                    } else {
-                        if ap_local_apic.flags & 1 == 1 {
-                            // Increase CPU ID
-                            CPU_COUNT.fetch_add(1, Ordering::SeqCst);
-
-                            // Allocate a stack
-                            let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET;
-                            let stack_end = stack_start + 64 * 4096;
-
-                            let ap_ready = TRAMPOLINE as *mut u64;
-                            let ap_cpu_id = unsafe { ap_ready.offset(1) };
-                            let ap_page_table = unsafe { ap_ready.offset(2) };
-                            let ap_stack_start = unsafe { ap_ready.offset(3) };
-                            let ap_stack_end = unsafe { ap_ready.offset(4) };
-                            let ap_code = unsafe { ap_ready.offset(5) };
-
-                            // Set the ap_ready to 0, volatile
-                            unsafe { atomic_store(ap_ready, 0) };
-                            unsafe { atomic_store(ap_cpu_id, ap_local_apic.id as u64) };
-                            unsafe { atomic_store(ap_page_table, active_table.address() as u64) };
-                            unsafe { atomic_store(ap_stack_start, stack_start as u64) };
-                            unsafe { atomic_store(ap_stack_end, stack_end as u64) };
-                            unsafe { atomic_store(ap_code, kstart_ap as u64) };
-                            AP_READY.store(false, Ordering::SeqCst);
-
-                            print!("        AP {}:", ap_local_apic.id);
-
-                            // Send INIT IPI
-                            {
-                                let mut icr = 0x4500;
-                                if local_apic.x2 {
-                                    icr |= (ap_local_apic.id as u64) << 32;
-                                } else {
-                                    icr |= (ap_local_apic.id as u64) << 56;
-                                }
-                                print!(" IPI...");
-                                local_apic.set_icr(icr);
-                            }
-
-                            // Send START IPI
-                            {
-                                //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
-                                let ap_segment = (AP_STARTUP >> 12) & 0xFF;
-                                let mut icr = 0x4600 | ap_segment as u64;
-
-                                if local_apic.x2 {
-                                    icr |= (ap_local_apic.id as u64) << 32;
-                                } else {
-                                    icr |= (ap_local_apic.id as u64) << 56;
-                                }
-
-                                print!(" SIPI...");
-                                local_apic.set_icr(icr);
-                            }
-
-                            // Wait for trampoline ready
-                            print!(" Wait...");
-                            while unsafe { atomic_load(ap_ready) } == 0 {
-                                interrupt::pause();
-                            }
-                            print!(" Trampoline...");
-                            while ! AP_READY.load(Ordering::SeqCst) {
-                                interrupt::pause();
-                            }
-                            println!(" Ready");
-
-                            active_table.flush_all();
-                        } else {
-                            println!("        CPU Disabled");
-                        }
-                    },
-                    _ => ()
-                }
-            }
-
-            // Unmap trampoline
-            let (result, _frame) = active_table.unmap_return(trampoline_page, false);
-            result.flush(active_table);
-        }
-    } else if let Some(dmar) = Dmar::new(sdt) {
-        println!(": {}: {}", dmar.addr_width, dmar.flags);
-
-        for dmar_entry in dmar.iter() {
-            println!("      {:?}", dmar_entry);
-            match dmar_entry {
-                DmarEntry::Drhd(dmar_drhd) => {
-                    let drhd = dmar_drhd.get(active_table);
-
-                    println!("VER: {:X}", drhd.version);
-                    println!("CAP: {:X}", drhd.cap);
-                    println!("EXT_CAP: {:X}", drhd.ext_cap);
-                    println!("GCMD: {:X}", drhd.gl_cmd);
-                    println!("GSTS: {:X}", drhd.gl_sts);
-                    println!("RT: {:X}", drhd.root_table);
-                },
-                _ => ()
-            }
-        }
-    } else if let Some(hpet) = Hpet::new(sdt) {
-        println!(": {}", hpet.hpet_number);
-        ACPI_TABLE.lock().hpet = Some(hpet);
-    } else if is_aml_table(sdt) {
-        ACPI_TABLE.lock().namespace = match parse_aml_table(sdt) {
-            Ok(res) => {
-                println!(": Parsed");
-                Some(res)
-            },
-            Err(AmlError::AmlParseError(e)) => {
-                println!(": {}", e);
-                None
-            }
-        };
+fn init_namespace() {
+    {
+        let mut namespace = ACPI_TABLE.namespace.write();
+        *namespace = Some(BTreeMap::new());
+    }
+    
+    let dsdt = find_sdt("DSDT");
+    if dsdt.len() == 1 {
+        print!("  DSDT");
+        load_table(get_sdt_signature(dsdt[0]));
+        init_aml_table(dsdt[0]);
     } else {
-        println!(": Unknown");
+        println!("Unable to find DSDT");
+        return;
+    };
+    
+    let ssdts = find_sdt("SSDT");
+
+    for ssdt in ssdts {
+        print!("  SSDT");
+        load_table(get_sdt_signature(ssdt));
+        init_aml_table(ssdt);
     }
 }
 
 /// Parse the ACPI tables to gather CPU, interrupt, and timer information
 pub unsafe fn init(active_table: &mut ActivePageTable) {
-    let start_addr = 0xE0000;
-    let end_addr = 0xFFFFF;
-
-    // Map all of the ACPI RSDP space
     {
-        let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
-        let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
-        for frame in Frame::range_inclusive(start_frame, end_frame) {
-            let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
-            let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
-            result.flush(active_table);
-        }
+        let mut sdt_ptrs = SDT_POINTERS.write();
+        *sdt_ptrs = Some(BTreeMap::new());
     }
 
+    {
+        let mut order = SDT_ORDER.write();
+        *order = Some(vec!());
+    }
+    
     // Search for RSDP
-    if let Some(rsdp) = RSDP::search(start_addr, end_addr) {
+    if let Some(rsdp) = RSDP::get_rsdp(active_table) {
         let rxsdt = get_sdt(rsdp.sdt_address(), active_table);
 
         for &c in rxsdt.signature.iter() {
             print!("{}", c as char);
         }
         println!(":");
-        if let Some(rsdt) = Rsdt::new(rxsdt) {
-            for sdt_address in rsdt.iter() {
-                let sdt = get_sdt(sdt_address, active_table);
-                parse_sdt(sdt, active_table);
-            }
+
+        let rxsdt: Box<Rxsdt + Send + Sync> = if let Some(rsdt) = Rsdt::new(rxsdt) {
+            Box::new(rsdt)
         } else if let Some(xsdt) = Xsdt::new(rxsdt) {
-            for sdt_address in xsdt.iter() {
-                let sdt = get_sdt(sdt_address, active_table);
-                parse_sdt(sdt, active_table);
-            }
+            Box::new(xsdt)
         } else {
             println!("UNKNOWN RSDT OR XSDT SIGNATURE");
+            return;
+        };
+        
+        rxsdt.map_all(active_table);
+        
+        for sdt_address in rxsdt.iter() {
+            let sdt = unsafe { &*(sdt_address as *const Sdt) };
+            
+            let signature = get_sdt_signature(sdt);
+            if let Some(ref mut ptrs) = *(SDT_POINTERS.write()) {
+                ptrs.insert(signature, sdt);
+            }
         }
+
+        Fadt::init(active_table);
+        Madt::init(active_table);
+        Dmar::init(active_table);
+        Hpet::init(active_table);
+        init_namespace();
     } else {
         println!("NO RSDP FOUND");
     }
+}
 
-    /* TODO: Cleanup mapping when looking for RSDP
-    // Unmap all of the ACPI RSDP space
-    {
-        let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
-        let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
-        for frame in Frame::range_inclusive(start_frame, end_frame) {
-            let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
-            let result = active_table.unmap(page);
-            result.flush(active_table);
+pub fn set_global_s_state(state: u8) {
+    if state == 5 {
+        let fadt = ACPI_TABLE.fadt.read();
+        
+        if let Some(ref fadt) = *fadt {
+            let port = fadt.pm1a_control_block as u16;
+            let mut val = 1 << 13;
+
+            let namespace = ACPI_TABLE.namespace.read();
+
+            if let Some(ref namespace) = *namespace {
+                if let Some(s) = namespace.get("\\_S5") {
+                    if let Ok(p) = s.get_as_package() {
+                        let slp_typa = p[0].get_as_integer().expect("SLP_TYPa is not an integer");
+                        let slp_typb = p[1].get_as_integer().expect("SLP_TYPb is not an integer");
+                        
+                        println!("Shutdown SLP_TYPa {:X}, SLP_TYPb {:X}", slp_typa, slp_typb);
+                        val |= slp_typa as u16;
+                        
+                        println!("Shutdown with ACPI outw(0x{:X}, 0x{:X})", port, val);
+                        Pio::<u16>::new(port).write(val);
+                    }
+                }
+            }
         }
     }
-    */
 }
 
-pub struct Acpi {
-    pub fadt: Option<Fadt>,
-    pub namespace: Option<AmlNamespace>,
-    pub hpet: Option<Hpet>
+type SdtSignature = (String, [u8; 6], [u8; 8]);
+pub static SDT_POINTERS: RwLock<Option<BTreeMap<SdtSignature, &'static Sdt>>> = RwLock::new(None);
+pub static SDT_ORDER: RwLock<Option<Vec<SdtSignature>>> = RwLock::new(None);
+
+pub fn find_sdt(name: &str) -> Vec<&'static Sdt> {
+    let mut sdts: Vec<&'static Sdt> = vec!();
+    
+    if let Some(ref ptrs) = *(SDT_POINTERS.read()) {
+        for (signature, sdt) in ptrs {
+            if signature.0 == name {
+                sdts.push(sdt);
+            }
+        }
+    }
+
+    sdts
 }
 
-pub static ACPI_TABLE: Mutex<Acpi> = Mutex::new(Acpi { fadt: None, namespace: None, hpet: None });
-
-/// RSDP
-#[derive(Copy, Clone, Debug)]
-#[repr(packed)]
-pub struct RSDP {
-    signature: [u8; 8],
-    checksum: u8,
-    oemid: [u8; 6],
-    revision: u8,
-    rsdt_address: u32,
-    length: u32,
-    xsdt_address: u64,
-    extended_checksum: u8,
-    reserved: [u8; 3]
+pub fn get_sdt_signature(sdt: &'static Sdt) -> SdtSignature {
+    let signature = String::from_utf8(sdt.signature.to_vec()).expect("Error converting signature to string");
+    (signature, sdt.oem_id, sdt.oem_table_id)
 }
 
-impl RSDP {
-    /// Search for the RSDP
-    pub fn search(start_addr: usize, end_addr: usize) -> Option<RSDP> {
-        for i in 0 .. (end_addr + 1 - start_addr)/16 {
-            let rsdp = unsafe { &*((start_addr + i * 16) as *const RSDP) };
-            if &rsdp.signature == b"RSD PTR " {
-                return Some(*rsdp);
-            }
+pub fn load_table(signature: SdtSignature) {
+    let mut order = SDT_ORDER.write();
+
+    if let Some(ref mut o) = *order {
+        o.push(signature);
+    }
+}
+
+pub fn get_signature_from_index(index: usize) -> Option<SdtSignature> {
+    if let Some(ref order) = *(SDT_ORDER.read()) {
+        if index < order.len() {
+            Some(order[index].clone())
+        } else {
+            None
         }
+    } else {
         None
     }
+}
 
-    /// Get the RSDT or XSDT address
-    pub fn sdt_address(&self) -> usize {
-        if self.revision >= 2 {
-            self.xsdt_address as usize
-        } else {
-            self.rsdt_address as usize
+pub fn get_index_from_signature(signature: SdtSignature) -> Option<usize> {
+    if let Some(ref order) = *(SDT_ORDER.read()) {
+        let mut i = order.len();
+        while i > 0 {
+            i -= 1;
+
+            if order[i] == signature {
+                return Some(i);
+            }
         }
     }
+
+    None
 }
+
+pub struct Acpi {
+    pub fadt: RwLock<Option<Fadt>>,
+    pub namespace: RwLock<Option<BTreeMap<String, AmlValue>>>,
+    pub hpet: RwLock<Option<Hpet>>,
+    pub next_ctx: RwLock<u64>,
+}
+
+pub static ACPI_TABLE: Acpi = Acpi {
+    fadt: RwLock::new(None),
+    namespace: RwLock::new(None),
+    hpet: RwLock::new(None),
+    next_ctx: RwLock::new(0),
+};
diff --git a/src/acpi/rsdp.rs b/src/acpi/rsdp.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3e25ec05203cecd0f4e701a63797232b05eabcf8
--- /dev/null
+++ b/src/acpi/rsdp.rs
@@ -0,0 +1,57 @@
+use memory::{allocate_frames, Frame};
+use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
+
+/// RSDP
+#[derive(Copy, Clone, Debug)]
+#[repr(packed)]
+pub struct RSDP {
+    signature: [u8; 8],
+    checksum: u8,
+    oemid: [u8; 6],
+    revision: u8,
+    rsdt_address: u32,
+    length: u32,
+    xsdt_address: u64,
+    extended_checksum: u8,
+    reserved: [u8; 3]
+}
+
+impl RSDP {
+    /// Search for the RSDP
+    pub fn get_rsdp(active_table: &mut ActivePageTable) -> Option<RSDP> {    
+        let start_addr = 0xE0000;
+        let end_addr = 0xFFFFF;
+        
+        // Map all of the ACPI RSDP space
+        {
+            let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
+            let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
+            for frame in Frame::range_inclusive(start_frame, end_frame) {
+                let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
+                let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
+                result.flush(active_table);
+            }
+        }
+
+        RSDP::search(start_addr, end_addr)
+    }
+    
+    fn search(start_addr: usize, end_addr: usize) -> Option<RSDP> {
+        for i in 0 .. (end_addr + 1 - start_addr)/16 {
+            let rsdp = unsafe { &*((start_addr + i * 16) as *const RSDP) };
+            if &rsdp.signature == b"RSD PTR " {
+                return Some(*rsdp);
+            }
+        }
+        None
+    }
+
+    /// Get the RSDT or XSDT address
+    pub fn sdt_address(&self) -> usize {
+        if self.revision >= 2 {
+            self.xsdt_address as usize
+        } else {
+            self.rsdt_address as usize
+        }
+    }
+}
diff --git a/src/acpi/rsdt.rs b/src/acpi/rsdt.rs
index fa391c0c678ca9eb31be84c54fc084ebb95a9ac8..7877a061801c4557c709bf222b2d0b07740cfa68 100644
--- a/src/acpi/rsdt.rs
+++ b/src/acpi/rsdt.rs
@@ -1,6 +1,8 @@
 use core::mem;
+use alloc::boxed::Box;
 
 use super::sdt::Sdt;
+use super::rxsdt::Rxsdt;
 
 #[derive(Debug)]
 pub struct Rsdt(&'static Sdt);
@@ -13,12 +15,14 @@ impl Rsdt {
             None
         }
     }
+}
 
-    pub fn iter(&self) -> RsdtIter {
-        RsdtIter {
+impl Rxsdt for Rsdt {
+    fn iter(&self) -> Box<Iterator<Item = usize>> {
+        Box::new(RsdtIter {
             sdt: self.0,
             i: 0
-        }
+        })
     }
 }
 
diff --git a/src/acpi/rxsdt.rs b/src/acpi/rxsdt.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8c7278be60204f4ce13201b88abf2aa64278a639
--- /dev/null
+++ b/src/acpi/rxsdt.rs
@@ -0,0 +1,28 @@
+use alloc::boxed::Box;
+
+use paging::ActivePageTable;
+
+use super::sdt::Sdt;
+use super::get_sdt;
+
+pub trait Rxsdt {
+    fn iter(&self) -> Box<Iterator<Item = usize>>;
+
+    fn map_all(&self, active_table: &mut ActivePageTable) {
+        for sdt in self.iter() {
+            get_sdt(sdt, active_table);
+        }
+    }
+            
+    fn find(&self, signature: [u8; 4], oem_id: [u8; 6], oem_table_id: [u8; 8]) -> Option<&'static Sdt> {
+        for sdt in self.iter() {
+            let sdt = unsafe { &*(sdt as *const Sdt) };
+            
+            if sdt.match_pattern(signature, oem_id, oem_table_id) {
+                return Some(sdt);
+            }
+        }
+
+        return None;
+    }
+}
diff --git a/src/acpi/sdt.rs b/src/acpi/sdt.rs
index 62d55cf472bb0e97ce31e68dc6f6d23be494a5a0..67dee89ba26e989a64eaf80cb4758c4c3c4db488 100644
--- a/src/acpi/sdt.rs
+++ b/src/acpi/sdt.rs
@@ -17,12 +17,12 @@ pub struct Sdt {
 
 impl Sdt {
     /// Get the address of this tables data
-    pub fn data_address(&'static self) -> usize {
+    pub fn data_address(&self) -> usize {
         self as *const _ as usize + mem::size_of::<Sdt>()
     }
 
     /// Get the length of this tables data
-    pub fn data_len(&'static self) -> usize {
+    pub fn data_len(&self) -> usize {
         let total_size = self.length as usize;
         let header_size = mem::size_of::<Sdt>();
         if total_size >= header_size {
@@ -32,7 +32,11 @@ impl Sdt {
         }
     }
 
-    pub fn data(&'static self) -> &[u8] {
+    pub fn data(&self) -> &[u8] {
         unsafe { slice::from_raw_parts(self.data_address() as *const u8, self.data_len()) }
     }
+    
+    pub fn match_pattern(&self, signature: [u8; 4], oem_id: [u8; 6], oem_table_id: [u8; 8]) -> bool{
+        self.signature == signature && self.oem_id == oem_id && self.oem_table_id == oem_table_id
+    }
 }
diff --git a/src/acpi/xsdt.rs b/src/acpi/xsdt.rs
index 5ec60361c43ac00fdec7293f2df342fe61ecf9d8..7339ce01e9577f5a800d743c5c9396d1e5306f05 100644
--- a/src/acpi/xsdt.rs
+++ b/src/acpi/xsdt.rs
@@ -1,6 +1,8 @@
 use core::mem;
+use alloc::boxed::Box;
 
 use super::sdt::Sdt;
+use super::rxsdt::Rxsdt;
 
 #[derive(Debug)]
 pub struct Xsdt(&'static Sdt);
@@ -13,12 +15,14 @@ impl Xsdt {
             None
         }
     }
+}
 
-    pub fn iter(&self) -> XsdtIter {
-        XsdtIter {
+impl Rxsdt for Xsdt {
+    fn iter(&self) -> Box<Iterator<Item = usize>> {
+        Box::new(XsdtIter {
             sdt: self.0,
             i: 0
-        }
+        })
     }
 }
 
diff --git a/src/arch/x86_64/device/hpet.rs b/src/arch/x86_64/device/hpet.rs
index 3f88f36896f473f5d651ead3c4a503977a145b0d..3490dee5b1697ededa3bc7fdbb3c4783b7ef06ba 100644
--- a/src/arch/x86_64/device/hpet.rs
+++ b/src/arch/x86_64/device/hpet.rs
@@ -1,19 +1,5 @@
-use core::intrinsics::{volatile_load, volatile_store};
-
-use memory::Frame;
-use paging::{entry, ActivePageTable, PhysicalAddress, Page, VirtualAddress};
-
 use acpi::hpet::Hpet;
 
-pub static mut HPET: HpetDevice = HpetDevice {
-    capability_addr: 0,
-    general_config_addr: 0,
-    general_interrupt_addr: 0,
-    main_counter_addr: 0,
-    t0_config_capability_addr: 0,
-    t0_comparator_addr: 0
-};
-
 static LEG_RT_CNF: u64 = 2;
 static ENABLE_CNF: u64 = 1;
 
@@ -21,62 +7,24 @@ static TN_VAL_SET_CNF: u64 = 0x40;
 static TN_TYPE_CNF: u64 = 0x08;
 static TN_INT_ENB_CNF: u64 = 0x04;
 
-pub struct HpetDevice {
-    capability_addr: usize,
-    general_config_addr: usize,
-    general_interrupt_addr: usize,
-    main_counter_addr: usize,
-    t0_config_capability_addr: usize,
-    t0_comparator_addr: usize
-}
-
-pub unsafe fn init(hpet: &Hpet, active_table: &mut ActivePageTable) {
-    HPET.init(hpet, active_table);
-}
-
-impl HpetDevice {
-    unsafe fn init(&mut self, hpet: &Hpet, active_table: &mut ActivePageTable) {
-        let base_address = hpet.base_address.address as usize;
-
-        self.capability_addr = base_address;
-        self.general_config_addr = base_address + 0x10;
-        self.general_interrupt_addr = base_address + 0x20;
-        self.main_counter_addr = base_address + 0xF0;
-
-        self.t0_config_capability_addr = base_address + 0x100;
-        self.t0_comparator_addr = base_address + 0x108;
-
-        {
-            let page = Page::containing_address(VirtualAddress::new(base_address));
-            let frame = Frame::containing_address(PhysicalAddress::new(base_address));
-            let result = active_table.map_to(page, frame, entry::PRESENT | entry::WRITABLE | entry::NO_EXECUTE);
-            result.flush(active_table);
-        }
-
-        println!("HPET mapped");
-
-        let counter_clk_period_fs = self.get_counter_clock_period();
-        let desired_fs_period: u64 = 2250286 * 1000000;
-
-        let clk_periods_per_kernel_tick: u64 = desired_fs_period / counter_clk_period_fs;
-
-        let enable_word: u64 = volatile_load(self.general_config_addr as *const u64)
-            | LEG_RT_CNF | ENABLE_CNF;
+static CAPABILITY_OFFSET: usize = 0x00;
+static GENERAL_CONFIG_OFFSET: usize = 0x10;
+// static GENERAL_INTERRUPT_OFFSET: usize = 0x20;
+// static MAIN_COUNTER_OFFSET: usize = 0xF0;
+static T0_CONFIG_CAPABILITY_OFFSET: usize = 0x100;
+static T0_COMPARATOR_OFFSET: usize = 0x108;
 
-        volatile_store(self.general_config_addr as *mut u64, enable_word);
-        // Enable interrupts from the HPET
+pub unsafe fn init(hpet: &mut Hpet) {
+    let counter_clk_period_fs = hpet.base_address.read_u64(CAPABILITY_OFFSET) >> 32;
+    let desired_fs_period: u64 = 2250286 * 1000000;
 
-        let t0_config_word: u64 = TN_VAL_SET_CNF | TN_TYPE_CNF | TN_INT_ENB_CNF;
-        volatile_store(self.t0_config_capability_addr as *mut u64, t0_config_word);
+    let clk_periods_per_kernel_tick: u64 = desired_fs_period / counter_clk_period_fs;
 
-        volatile_store(self.t0_comparator_addr as *mut u64, clk_periods_per_kernel_tick);
-    }
+    let enable_word: u64 = hpet.base_address.read_u64(GENERAL_CONFIG_OFFSET) | LEG_RT_CNF | ENABLE_CNF;
+    hpet.base_address.write_u64(GENERAL_CONFIG_OFFSET, enable_word);
+    // Enable interrupts from the HPET
 
-    pub fn get_counter_clock_period(&self) -> u64 {
-        unsafe { volatile_load(self.capability_addr as *const u64) >> 32 }
-    }
-    
-    pub fn get_main_counter(&self) -> u64 {
-        unsafe { volatile_load(self.main_counter_addr as *const u64) }
-    }
+    let t0_config_word: u64 = TN_VAL_SET_CNF | TN_TYPE_CNF | TN_INT_ENB_CNF;
+    hpet.base_address.write_u64(T0_CONFIG_CAPABILITY_OFFSET, t0_config_word);
+    hpet.base_address.write_u64(T0_COMPARATOR_OFFSET, clk_periods_per_kernel_tick);
 }
diff --git a/src/arch/x86_64/device/mod.rs b/src/arch/x86_64/device/mod.rs
index 965e0834e121d52c50230daaf1cbd271ed3b6bb8..b7b9ceac67d648dc5b5e7bf3667ba6c02dda5e6d 100644
--- a/src/arch/x86_64/device/mod.rs
+++ b/src/arch/x86_64/device/mod.rs
@@ -1,6 +1,5 @@
 use paging::ActivePageTable;
 use acpi::ACPI_TABLE;
-use syscall::io::{Pio, Io};
 
 pub mod cpu;
 pub mod local_apic;
@@ -15,10 +14,10 @@ pub unsafe fn init(active_table: &mut ActivePageTable){
     local_apic::init(active_table);
 }
 
-pub unsafe fn init_noncore(active_table: &mut ActivePageTable) {
+pub unsafe fn init_noncore() {
     {
-        if let Some(ref hpet) = ACPI_TABLE.lock().hpet {
-            hpet::init(hpet, active_table);
+        if let Some(ref mut hpet) = *ACPI_TABLE.hpet.write() {
+            hpet::init(hpet);
         } else {
             pit::init();
         }
diff --git a/src/arch/x86_64/start.rs b/src/arch/x86_64/start.rs
index cd3c0c44b27c06cd445d32eedc3bc1cc3a53cf33..d2995e654edfb5b838cbc1802c78682f7f02792c 100644
--- a/src/arch/x86_64/start.rs
+++ b/src/arch/x86_64/start.rs
@@ -15,6 +15,8 @@ use memory;
 use paging::{self, entry, Page, VirtualAddress};
 use paging::mapper::MapperFlushAll;
 
+use stop;
+
 /// Test of zero values in BSS.
 static BSS_TEST_ZERO: usize = 0;
 /// Test of non-zero values in data.
@@ -107,7 +109,7 @@ pub unsafe extern fn kstart(kernel_base: usize, kernel_size: usize, stack_base:
         acpi::init(&mut active_table);
 
         // Initialize all of the non-core devices not otherwise needed to complete initialization
-        device::init_noncore(&mut active_table);
+        device::init_noncore();
 
         // Initialize memory functions after core has loaded
         memory::init_noncore();
diff --git a/src/arch/x86_64/stop.rs b/src/arch/x86_64/stop.rs
index 45b8d7d8f6b94c8d435f5c4e4838757922b83d84..c65768cc104b7387f4e9b0b1cfb2e00740ab1019 100644
--- a/src/arch/x86_64/stop.rs
+++ b/src/arch/x86_64/stop.rs
@@ -21,29 +21,7 @@ pub unsafe extern fn kreset() -> ! {
 #[no_mangle]
 pub unsafe extern fn kstop() -> ! {
     println!("kstop");
-
-    // ACPI shutdown
-    {
-        let acpi = acpi::ACPI_TABLE.lock();
-        if let Some(ref fadt) = acpi.fadt {
-            let port = fadt.pm1a_control_block as u16;
-            let mut val = 1 << 13;
-            if let Some(ref namespace) = acpi.namespace {
-                if let Some(s) = namespace.find_str("\\_S5") {
-                    if let Some(p) = s.get_as_package() {
-                        let slp_typa = p[0].get_as_integer().expect("SLP_TYPa is not an integer");
-                        let slp_typb = p[1].get_as_integer().expect("SLP_TYPb is not an integer");
-
-                        println!("Shutdown SLP_TYPa {:X}, SLP_TYPb {:X}", slp_typa, slp_typb);
-                        val |= slp_typa as u16;
-                    }
-                }
-            }
-
-            println!("Shutdown with ACPI outw(0x{:X}, 0x{:X})", port, val);
-            Pio::<u16>::new(port).write(val);
-        }
-    }
+    acpi::set_global_s_state(5);
 
     // Magic shutdown code for bochs and qemu (older versions).
     for c in "Shutdown".bytes() {
diff --git a/src/lib.rs b/src/lib.rs
index 33e746aec4273fe8f0b5c5e8442d3b3edc9a76c1..d0a1a2250082e03926418557cda24410a56e3920 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,6 +19,7 @@
 #![feature(never_type)]
 #![feature(thread_local)]
 #![feature(unique)]
+#![feature(conservative_impl_trait)]
 #![no_std]
 
 extern crate alloc_kernel as allocator;