diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 76a1007ad4c1d5a8bd1ebf369dd1ac08ee6723b1..9574ec20a435cbca1cedfd9d3264690040715dba 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,15 +1,18 @@
 before_script:
   - apt-get update -qq
   - apt-get install -qq build-essential curl git
-  - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly
+  - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable
   - source "$HOME/.cargo/env"
 
-linux-nightly:
+linux:
   script:
     - cargo build
     - make tests
+  cache:
+    paths:
+      - target
 
-redox-nightly:
+redox:
   variables:
     CC: "x86_64-unknown-redox-gcc"
   before_script:
@@ -23,3 +26,6 @@ redox-nightly:
     - rustup target add x86_64-unknown-redox
   script:
     - cargo build --target x86_64-unknown-redox
+  cache:
+    paths:
+      - target
diff --git a/Cargo.lock b/Cargo.lock
index 052f75a3dfd76d29aa217b1899bcdbb525d1b69b..a687b991876a5570c85a19cc24776e8a154299bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16,7 +16,7 @@ dependencies = [
 
 [[package]]
 name = "atty"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -32,7 +32,7 @@ dependencies = [
  "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -60,7 +60,7 @@ name = "calculate"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "decimal 2.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "liner 0.4.5 (git+https://gitlab.redox-os.org/redox-os/liner)",
@@ -82,7 +82,7 @@ version = "2.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -171,13 +171,13 @@ dependencies = [
  "ion_ranges 0.1.0",
  "ion_sys 0.1.0",
  "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "liner 0.4.5 (git+https://gitlab.redox-os.org/redox-os/liner)",
  "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "small 0.1.0 (git+https://gitlab.redox-os.org/redox-os/small)",
- "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "xdg 2.1.0 (git+https://github.com/whitequark/rust-xdg)",
@@ -189,7 +189,7 @@ version = "0.1.0"
 dependencies = [
  "permutate 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "small 0.1.0 (git+https://gitlab.redox-os.org/redox-os/small)",
- "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -200,7 +200,7 @@ dependencies = [
  "calculate 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "small 0.1.0 (git+https://gitlab.redox-os.org/redox-os/small)",
- "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -234,7 +234,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "lazy_static"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -316,19 +316,19 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -336,7 +336,7 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.8"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -356,8 +356,11 @@ source = "git+https://gitlab.redox-os.org/redox-os/small#b3d41e641b5318080c652f2
 
 [[package]]
 name = "smallvec"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 [[package]]
 name = "strsim"
@@ -414,7 +417,7 @@ name = "thread_local"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -501,7 +504,7 @@ source = "git+https://github.com/whitequark/rust-xdg#090afef2509d746e48d6bfa9b2e
 [metadata]
 "checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
+"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
 "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
 "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e"
 "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
@@ -519,7 +522,7 @@ source = "git+https://github.com/whitequark/rust-xdg#090afef2509d746e48d6bfa9b2e
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
-"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
+"checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3"
 "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
 "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2"
 "checksum liner 0.4.5 (git+https://gitlab.redox-os.org/redox-os/liner)" = "<none>"
@@ -531,13 +534,13 @@ source = "git+https://github.com/whitequark/rust-xdg#090afef2509d746e48d6bfa9b2e
 "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
 "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
-"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e"
-"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54"
-"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
+"checksum regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbbea44c5490a1e84357ff28b7d518b4619a159fed5d25f6c1de2d19cc42814"
+"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
+"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920"
 "checksum small 0.1.0 (git+https://gitlab.redox-os.org/redox-os/small)" = "<none>"
-"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514"
+"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
 "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
diff --git a/Cargo.toml b/Cargo.toml
index a483624b294dccca2dec56aff02efa0e37511b38..777eefd4643dbb6a02b6c048f36dd311cb4d359c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,11 +2,13 @@
 
 authors = [
     "Michael Aaron Murphy <mmstickman@gmail.com>",
-    "Hunter Goldstein <hunter.d.goldstein@gmail.com>",
-    "Skyler Berg <skylertheberg@gmail.com>",
     "Jeremy Soller <jackpot51@gmail.com>",
-    "Michael Gattozzi <mgattozzi@gmail.com>",
-    "Łukasz Niemier <lukasz@niemier.pl>",
+    "Skyler Berg <skylertheberg@gmail.com>",
+    "stratact <stratact1@gmail.com>",
+    "Hunter Goldstein <hunter.d.goldstein@gmail.com>",
+    "jD91mZM2 <me@krake.one>",
+    "Agustin Chiappe Berrini <jnieve@gmail.com>",
+    "Sag0Sag0 <Sag0Sag0@users.noreply.github.com>",
 ]
 build = "build.rs"
 description = "The Ion Shell"
diff --git a/build.rs b/build.rs
index 2fd196ccda079f9c8f780ca54b99306aa0ef799f..c3760a51d9a17091cc49ab8a7b6d1e28b57df045 100644
--- a/build.rs
+++ b/build.rs
@@ -1,9 +1,3 @@
-extern crate ansi_term;
-extern crate version_check;
-
-use ansi_term::Color::{Blue, Red, White};
-use version_check::supports_features;
-
 // Specifies the minimum version needed to compile Ion.
 // NOTE: 1.19 is required due to the usage of `break` with values for
 // `loop` (RFC 1624, rust-lang/rust GitHub issue #37339).
@@ -14,34 +8,6 @@ use std::{
 };
 
 fn main() {
-    match supports_features() {
-        Some(true) => (), // Success!
-        Some(false) => {
-            eprintln!(
-                "{} {}",
-                Red.bold().paint("Error:"),
-                White.paint("Ion requires nightly/dev to build.")
-            );
-            // print_version_err(&*version_string);
-            eprintln!(
-                "{}{}{}",
-                Blue.paint("Use `"),
-                White.paint("rustup update"),
-                Blue.paint("` to update to the latest nightly compiler.")
-            );
-            panic!("Aborting compilation due to incompatible compiler.")
-        }
-        _ => {
-            eprintln!(
-                "cargo:warning={}",
-                "Ion was unable to check rustc compatibility."
-            );
-            eprintln!(
-                "cargo:warning={}",
-                "Build may fail due to incompatible rustc version."
-            );
-        }
-    }
     match write_version_file() {
         Ok(_) => {}
         Err(e) => panic!("Failed to create a version file: {:?}", e),
diff --git a/members/lexers/src/assignments/keys.rs b/members/lexers/src/assignments/keys.rs
index cf503166d6e0a162d9f0c543760f6c4a70b10ac9..2b297c0f0cf4ef1c4abe5a72a369ae850f8289ed 100644
--- a/members/lexers/src/assignments/keys.rs
+++ b/members/lexers/src/assignments/keys.rs
@@ -137,10 +137,12 @@ impl<'a> Iterator for KeyIterator<'a> {
                     }))
                 }
                 b':' => {
-                    return Some(self.parse_parameter(&self.data[start..self.read - 1].trim()));
+                    let end = self.read - 1;
+                    return Some(self.parse_parameter(&self.data[start..end].trim()));
                 }
                 b'[' => {
-                    return Some(self.parse_array(&self.data[start..self.read - 1].trim()));
+                    let end = self.read - 1;
+                    return Some(self.parse_array(&self.data[start..end].trim()));
                 }
                 _ => (),
             }
diff --git a/members/lexers/src/lib.rs b/members/lexers/src/lib.rs
index 7d273c0134464107e657ef4c487d9055d0d88632..647eabfb45c63c2fc1b9f0415d6618b338dde810 100644
--- a/members/lexers/src/lib.rs
+++ b/members/lexers/src/lib.rs
@@ -1,4 +1,3 @@
-#![feature(nll)]
 #[macro_use]
 extern crate bitflags;
 
diff --git a/src/lib/lib.rs b/src/lib/lib.rs
index 793ad0bac19ed0527011163dfe8a9438431c0e0a..b652e9108aca32989d3728014b9e4eb5f136635e 100644
--- a/src/lib/lib.rs
+++ b/src/lib/lib.rs
@@ -1,6 +1,5 @@
 #![allow(unknown_lints)]
 #![allow(while_let_on_iterator)]
-#![feature(nll)]
 
 #[macro_use]
 extern crate bitflags;
diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs
index a0cfe827d3b15b94c8372af3de0efbeb31478d74..6750de0f1db77e775d82144dcffcee76bc0179b8 100644
--- a/src/lib/shell/flow.rs
+++ b/src/lib/shell/flow.rs
@@ -573,7 +573,8 @@ impl FlowLogic for Shell {
                     SUCCESS => self.previous_status = FAILURE,
                     _ => (),
                 }
-                self.set("?", self.previous_status.to_string());
+                let previous_status = self.previous_status.to_string();
+                self.set("?", previous_status);
             }
             Statement::Break => return Condition::Break,
             Statement::Continue => return Condition::Continue,
diff --git a/src/lib/shell/variables/mod.rs b/src/lib/shell/variables/mod.rs
index dcac0a6df6474f12fea4126c013eee5abc567b5e..93c86039d1e97241bc1163c2cdc5f8ddcbf0f2d3 100644
--- a/src/lib/shell/variables/mod.rs
+++ b/src/lib/shell/variables/mod.rs
@@ -546,75 +546,123 @@ impl Variables {
 
     pub fn set<T: Into<VariableType>>(&mut self, name: &str, var: T) {
         let var = var.into();
-        match self.get_mut(&name) {
-            Some(VariableType::Str(ref mut str_)) => {
-                if !name.is_empty() {
-                    if let VariableType::Str(var_str) = var {
-                        if var_str.is_empty() {
-                            self.remove_variable(name);
-                        } else {
-                            if name == "NS_PLUGINS" {
-                                match &*var_str {
-                                    "0" => self.disable_plugins(),
-                                    "1" => self.enable_plugins(),
-                                    _ => eprintln!(
-                                        "ion: unsupported value for NS_PLUGINS. Value must be either 0 or 1."
-                                    ),
-                                }
-                                return;
+        enum UpperAction {
+            Remove,
+            Shadow,
+        }
+
+        enum Action<'a> {
+            UpperAction(UpperAction),
+            ReplaceAlias(&'a mut types::Alias),
+            ReplaceString(&'a mut types::Str),
+            ReplaceArray(&'a mut types::Array),
+            ReplaceFunction(&'a mut Function),
+            ReplaceHMap(&'a mut types::HashMap),
+        }
+
+        let mut upper_action = None;
+
+        {
+            let mut action = None;
+            let key = self.get_mut(&name);
+
+            match key {
+                Some(VariableType::Str(ref mut str_)) => {
+                    if !name.is_empty() {
+                        if let VariableType::Str(var_str) = &var {
+                            if var_str.is_empty() {
+                                action = Some(Action::UpperAction(UpperAction::Remove));
+                            } else {
+                                action = Some(Action::ReplaceString(str_));
                             }
-                            mem::replace(str_, var_str);
+                        } else {
+                            action = Some(Action::UpperAction(UpperAction::Shadow));
                         }
-                    } else {
-                        self.shadow(name.into(), var);
                     }
                 }
-            }
-            Some(VariableType::Alias(ref mut alias)) => {
-                if !name.is_empty() {
-                    if let VariableType::Alias(var_alias) = var {
-                        mem::replace(alias, var_alias);
-                    } else {
-                        self.shadow(name.into(), var);
+                Some(VariableType::Alias(ref mut alias)) => {
+                    if !name.is_empty() {
+                        if let VariableType::Alias(_) = &var {
+                            action = Some(Action::ReplaceAlias(alias))
+                        } else {
+                            action = Some(Action::UpperAction(UpperAction::Shadow));
+                        }
                     }
                 }
-            }
-            Some(VariableType::Array(ref mut array)) => {
-                if !name.is_empty() {
-                    if let VariableType::Array(var_array) = var {
-                        if var_array.is_empty() {
-                            self.remove_variable(name);
+                Some(VariableType::Array(ref mut array)) => {
+                    if !name.is_empty() {
+                        if let VariableType::Array(var_array) = &var {
+                            if var_array.is_empty() {
+                                action = Some(Action::UpperAction(UpperAction::Remove));
+                            } else {
+                                action = Some(Action::ReplaceArray(array))
+                            }
                         } else {
-                            mem::replace(array, var_array);
+                            action = Some(Action::UpperAction(UpperAction::Shadow));
                         }
-                    } else {
-                        self.shadow(name.into(), var);
                     }
                 }
-            }
-            Some(VariableType::HashMap(ref mut map)) => {
-                if !name.is_empty() {
-                    if let VariableType::HashMap(var_map) = var {
-                        if var_map.is_empty() {
-                            self.remove_variable(name);
+                Some(VariableType::HashMap(ref mut map)) => {
+                    if !name.is_empty() {
+                        if let VariableType::HashMap(var_map) = &var {
+                            if var_map.is_empty() {
+                                action = Some(Action::UpperAction(UpperAction::Remove));
+                            } else {
+                                action = Some(Action::ReplaceHMap(map))
+                            }
                         } else {
-                            mem::replace(map, var_map);
+                            action = Some(Action::UpperAction(UpperAction::Shadow));
                         }
-                    } else {
-                        self.shadow(name.into(), var);
                     }
                 }
-            }
-            Some(VariableType::Function(ref mut func)) => {
-                if !name.is_empty() {
-                    if let VariableType::Function(var_func) = var {
-                        mem::replace(func, var_func);
-                    } else {
-                        self.shadow(name.into(), var);
+                Some(VariableType::Function(ref mut func)) => {
+                    if !name.is_empty() {
+                        if let VariableType::Function(_) = &var {
+                            action = Some(Action::ReplaceFunction(func))
+                        } else {
+                            action = Some(Action::UpperAction(UpperAction::Shadow));
+                        }
                     }
                 }
+                _ => {
+                    action = Some(Action::UpperAction(UpperAction::Shadow));
+                }
+            };
+
+            match action {
+                Some(Action::UpperAction(action)) => upper_action = Some((action, var)),
+                Some(Action::ReplaceAlias(alias)) => match var {
+                    VariableType::Alias(mut alias_) => { mem::replace(alias, alias_); }
+                    _ => unreachable!()
+                }
+                Some(Action::ReplaceArray(array)) => match var {
+                    VariableType::Array(mut  array_) => { mem::replace(array, array_); }
+                    _ => unreachable!()
+                }
+                Some(Action::ReplaceString(str_)) => match var {
+                    VariableType::Str(mut var_str) => { mem::replace(str_, var_str); }
+                    _ => unreachable!()
+                }
+                Some(Action::ReplaceFunction(func)) => match var {
+                    VariableType::Function(mut  func_) => { mem::replace(func, func_); }
+                    _ => unreachable!()
+                }
+                Some(Action::ReplaceHMap(hmap)) => match var {
+                    VariableType::HashMap(mut  hmap_) => { mem::replace(hmap, hmap_); }
+                    _ => unreachable!()
+                }
+                None => ()
+            }
+        }
+
+        match upper_action {
+            Some((UpperAction::Remove, _)) => {
+                self.remove_variable(name);
+            }
+            Some((UpperAction::Shadow, var)) => {
+                self.shadow(name.into(), var);
             }
-            _ => { self.shadow(name.into(), var); }
+            None => ()
         }
     }