diff --git a/modules/client_terminal/terminal.lua b/modules/client_terminal/terminal.lua
index 2c88bf00..3d685bc6 100644
--- a/modules/client_terminal/terminal.lua
+++ b/modules/client_terminal/terminal.lua
@@ -12,7 +12,8 @@ local MaxHistory = 1000
 local terminalWindow
 local terminalButton
 local logLocked = false
-local commandEnv = newenv()
+local commandEnv = {}
+setmetatable(commandEnv, { __index = getfenv() } )
 local commandTextEdit
 local terminalBuffer
 local commandHistory = { }
diff --git a/modules/corelib/util.lua b/modules/corelib/util.lua
index eead1ee2..066638e1 100644
--- a/modules/corelib/util.lua
+++ b/modules/corelib/util.lua
@@ -110,6 +110,46 @@ function extends(base)
   return derived
 end
 
+function runinsandbox(func, ...)
+  if type(func) == 'string' then
+    func, err = loadfile(resolvepath(func, 2))
+    if not func then
+      error(err)
+    end
+  end
+  local env = { }
+  local oldenv = getfenv(0)
+  setmetatable(env, { __index = oldenv } )
+  setfenv(0, env)
+  func(...)
+  setfenv(0, oldenv)
+  return env
+end
+
+function loadasmodule(name, file)
+  file = file or resolvepath(name, 2)
+  if package.loaded[name] then
+    return package.loaded[name]
+  end
+  local env = runinsandbox(file)
+  package.loaded[name] = env
+  return env
+end
+
+local function module_loader(modname)
+  local module = g_modules.getModule(modname)
+  if not module then
+    return '\n\tno module \'' .. modname .. '\''
+  end
+  return function()
+    if not module:load() then
+      error('unable to load required module ' .. modname)
+    end
+    return module:getSandbox()
+  end
+end
+table.insert(package.loaders, 1, module_loader)
+
 function export(what, key)
   if key ~= nil then
     _G[key] = what
@@ -130,17 +170,6 @@ function unexport(key)
   end
 end
 
-function sandbox(what)
-  what = what or 2
-  setfenv(what, newenv())
-end
-
-function newenv()
-  local env = { }
-  setmetatable(env, { __index = getfenv() } )
-  return env
-end
-
 function getfsrcpath(depth)
   depth = depth or 2
   local info = debug.getinfo(1+depth, "Sn")
diff --git a/modules/game_skills/skills.lua b/modules/game_skills/skills.lua
index ecaec384..229050e2 100644
--- a/modules/game_skills/skills.lua
+++ b/modules/game_skills/skills.lua
@@ -1,17 +1,52 @@
-Skills = {}
+skillsWindow = nil
+skillsButton = nil
 
--- private variables
-local skillsWindow
-local skillsButton
+function init()
+  connect(LocalPlayer, {
+    onExperienceChange = onExperienceChange,
+    onLevelChange = onLevelChange,
+    onHealthChange = onHealthChange,
+    onManaChange = onManaChange,
+    onSoulChange = onSoulChange,
+    onFreeCapacityChange = onFreeCapacityChange,
+    onStaminaChange = onStaminaChange,
+    onMagicLevelChange = onMagicLevelChange,
+    onSkillChange = onSkillChange
+  })
 
--- private functions
-local function setSkillValue(id, value)
+  skillsWindow = g_ui.loadUI('skills.otui', GameInterface.getRightPanel())
+  skillsButton = TopMenu.addRightGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', toggle)
+  skillsButton:setOn(true)
+  g_keyboard.bindKeyDown('Ctrl+S', toggle)
+
+  refresh()
+end
+
+function terminate()
+  disconnect(LocalPlayer, {
+    onExperienceChange = onExperienceChange,
+    onLevelChange = onLevelChange,
+    onHealthChange = onHealthChange,
+    onManaChange = onManaChange,
+    onSoulChange = onSoulChange,
+    onFreeCapacityChange = onFreeCapacityChange,
+    onStaminaChange = onStaminaChange,
+    onMagicLevelChange = onMagicLevelChange,
+    onSkillChange = onSkillChange
+  })
+
+  g_keyboard.unbindKeyDown('Ctrl+S')
+  skillsButton:destroy()
+  skillsWindow:destroy()
+end
+
+function setSkillValue(id, value)
   local skill = skillsWindow:recursiveGetChildById(id)
   local widget = skill:getChildById('value')
   widget:setText(value)
 end
 
-local function setSkillPercent(id, percent, tooltip)
+function setSkillPercent(id, percent, tooltip)
   local skill = skillsWindow:recursiveGetChildById(id)
   local widget = skill:getChildById('percent')
   widget:setPercent(percent)
@@ -21,69 +56,25 @@ local function setSkillPercent(id, percent, tooltip)
   end
 end
 
--- public functions
-function Skills.init()
-  connect(LocalPlayer, {
-    onExperienceChange = Skills.onExperienceChange,
-    onLevelChange = Skills.onLevelChange,
-    onHealthChange = Skills.onHealthChange,
-    onManaChange = Skills.onManaChange,
-    onSoulChange = Skills.onSoulChange,
-    onFreeCapacityChange = Skills.onFreeCapacityChange,
-    onStaminaChange = Skills.onStaminaChange,
-    onMagicLevelChange = Skills.onMagicLevelChange,
-    onSkillChange = Skills.onSkillChange
-  })
-
-  skillsWindow = g_ui.loadUI('skills.otui', GameInterface.getRightPanel())
-  skillsButton = TopMenu.addRightGameToggleButton('skillsButton', tr('Skills') .. ' (Ctrl+S)', 'skills.png', Skills.toggle)
-  skillsButton:setOn(true)
-  g_keyboard.bindKeyDown('Ctrl+S', Skills.toggle)
-
-  Skills.refresh()
-end
-
-function Skills.terminate()
-  disconnect(LocalPlayer, {
-    onExperienceChange = Skills.onExperienceChange,
-    onLevelChange = Skills.onLevelChange,
-    onHealthChange = Skills.onHealthChange,
-    onManaChange = Skills.onManaChange,
-    onSoulChange = Skills.onSoulChange,
-    onFreeCapacityChange = Skills.onFreeCapacityChange,
-    onStaminaChange = Skills.onStaminaChange,
-    onMagicLevelChange = Skills.onMagicLevelChange,
-    onSkillChange = Skills.onSkillChange
-  })
-
-  g_keyboard.unbindKeyDown('Ctrl+S')
-  skillsButton:destroy()
-  skillsButton = nil
-  skillsWindow:destroy()
-  skillsWindow = nil
-
-  Skills = nil
-end
-
-function Skills.refresh()
+function refresh()
   local player = g_game.getLocalPlayer()
   if not player then return end
 
-  Skills.onExperienceChange(player, player:getExperience())
-  Skills.onLevelChange(player, player:getLevel(), player:getLevelPercent())
-  Skills.onHealthChange(player, player:getHealth(), player:getMaxHealth())
-  Skills.onManaChange(player, player:getMana(), player:getMaxMana())
-  Skills.onSoulChange(player, player:getSoul())
-  Skills.onFreeCapacityChange(player, player:getFreeCapacity())
-  Skills.onStaminaChange(player, player:getStamina())
-  Skills.onMagicLevelChange(player, player:getMagicLevel(), player:getMagicLevelPercent())
+  onExperienceChange(player, player:getExperience())
+  onLevelChange(player, player:getLevel(), player:getLevelPercent())
+  onHealthChange(player, player:getHealth(), player:getMaxHealth())
+  onManaChange(player, player:getMana(), player:getMaxMana())
+  onSoulChange(player, player:getSoul())
+  onFreeCapacityChange(player, player:getFreeCapacity())
+  onStaminaChange(player, player:getStamina())
+  onMagicLevelChange(player, player:getMagicLevel(), player:getMagicLevelPercent())
 
   for i=0,6 do
-    Skills.onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i))
+    onSkillChange(player, i, player:getSkillLevel(i), player:getSkillLevelPercent(i))
   end
 end
 
-function Skills.toggle()
+function toggle()
   if skillsButton:isOn() then
     skillsWindow:close()
     skillsButton:setOn(false)
@@ -93,11 +84,11 @@ function Skills.toggle()
   end
 end
 
-function Skills.onMiniWindowClose()
+function onMiniWindowClose()
   skillsButton:setOn(false)
 end
 
-function Skills.onSkillButtonClick(button)
+function onSkillButtonClick(button)
   local percentBar = button:getChildById('percent')
   if percentBar then
     percentBar:setVisible(not percentBar:isVisible())
@@ -109,33 +100,32 @@ function Skills.onSkillButtonClick(button)
   end
 end
 
--- hooked events
-function Skills.onExperienceChange(localPlayer, value)
+function onExperienceChange(localPlayer, value)
   setSkillValue('experience', tr(value))
 end
 
-function Skills.onLevelChange(localPlayer, value, percent)
+function onLevelChange(localPlayer, value, percent)
   setSkillValue('level', tr(value))
   setSkillPercent('level', percent, tr('You have %s percent to go', 100 - percent))
 end
 
-function Skills.onHealthChange(localPlayer, health, maxHealth)
+function onHealthChange(localPlayer, health, maxHealth)
   setSkillValue('health', tr(health))
 end
 
-function Skills.onManaChange(localPlayer, mana, maxMana)
+function onManaChange(localPlayer, mana, maxMana)
   setSkillValue('mana', tr(mana))
 end
 
-function Skills.onSoulChange(localPlayer, soul)
+function onSoulChange(localPlayer, soul)
   setSkillValue('soul', soul)
 end
 
-function Skills.onFreeCapacityChange(localPlayer, freeCapacity)
+function onFreeCapacityChange(localPlayer, freeCapacity)
   setSkillValue('capacity', freeCapacity)
 end
 
-function Skills.onStaminaChange(localPlayer, stamina)
+function onStaminaChange(localPlayer, stamina)
   local hours = math.floor(stamina / 60)
   local minutes = stamina % 60
   if minutes < 10 then
@@ -147,12 +137,12 @@ function Skills.onStaminaChange(localPlayer, stamina)
   setSkillPercent('stamina', percent, tr('You have %s percent', percent))
 end
 
-function Skills.onMagicLevelChange(localPlayer, value, percent)
+function onMagicLevelChange(localPlayer, value, percent)
   setSkillValue('magiclevel', value)
   setSkillPercent('magiclevel', percent, tr('You have %s percent to go', 100 - percent))
 end
 
-function Skills.onSkillChange(localPlayer, id, level, percent)
+function onSkillChange(localPlayer, id, level, percent)
   setSkillValue('skillId' .. id, level)
   setSkillPercent('skillId' .. id, percent, tr('You have %s percent to go', 100 - percent))
 end
diff --git a/modules/game_skills/skills.otmod b/modules/game_skills/skills.otmod
index 04cff361..c4ff4016 100644
--- a/modules/game_skills/skills.otmod
+++ b/modules/game_skills/skills.otmod
@@ -3,13 +3,12 @@ Module
   description: Manage skills window
   author: baxnie, edubart
   website: www.otclient.info
+  sandboxed: true
+  scripts:
+    - skills.lua
 
   dependencies:
     - game_interface
 
-  @onLoad: |
-    dofile 'skills'
-    Skills.init()
-
-  @onUnload: |
-    Skills.terminate()
+  @onLoad: init()
+  @onUnload: terminate()
diff --git a/modules/game_skills/skills.otui b/modules/game_skills/skills.otui
index be1082b0..a3792382 100644
--- a/modules/game_skills/skills.otui
+++ b/modules/game_skills/skills.otui
@@ -3,7 +3,7 @@ SkillFirstWidget < UIWidget
 SkillButton < UIButton
   height: 21
   margin-bottom: 2
-  &onClick: Skills.onSkillButtonClick
+  &onClick: onSkillButtonClick
 
 SkillNameLabel < GameLabel
   font: verdana-11px-monochrome
@@ -35,7 +35,7 @@ MiniWindow
   !text: tr('Skills')
   height: 150
   icon: skills.png
-  @onClose: Skills.onMiniWindowClose()
+  @onClose: onMiniWindowClose()
   &save: true
 
   MiniWindowContents
diff --git a/src/framework/core/module.cpp b/src/framework/core/module.cpp
index 63a55455..563cf6bf 100644
--- a/src/framework/core/module.cpp
+++ b/src/framework/core/module.cpp
@@ -30,8 +30,7 @@
 Module::Module(const std::string& name)
 {
     m_name = name;
-    g_lua.newEnvironment();
-    m_sandboxEnv = g_lua.ref();
+    m_sandboxEnv = g_lua.newSandboxEnv();
 }
 
 bool Module::load()
@@ -49,12 +48,11 @@ bool Module::load()
                 stdext::throw_exception(stdext::format("dependency '%s' has failed to load", m_name, depName));
         }
 
+        if(m_sandboxed)
+            g_lua.setGlobalEnvironment(m_sandboxEnv);
+
         for(const std::string& script : m_scripts) {
             g_lua.loadScript(script);
-            if(m_sandboxed) {
-                g_lua.getRef(m_sandboxEnv);
-                g_lua.setEnv();
-            }
             g_lua.safeCall(0, 0);
         }
 
@@ -69,8 +67,13 @@ bool Module::load()
             g_lua.safeCall(0, 0);
         }
 
+        if(m_sandboxed)
+            g_lua.resetGlobalEnvironment();
+
         g_logger.debug(stdext::format("Loaded module '%s'", m_name));
     } catch(stdext::exception& e) {
+        if(m_sandboxed)
+            g_lua.resetGlobalEnvironment();
         g_logger.error(stdext::format("Unable to load module '%s': %s", m_name, e.what()));
         return false;
     }
@@ -93,20 +96,29 @@ void Module::unload()
 {
     if(m_loaded) {
         try {
+            if(m_sandboxed)
+                g_lua.setGlobalEnvironment(m_sandboxEnv);
+
             const std::string& onUnloadBuffer = std::get<0>(m_onUnloadFunc);
             const std::string& onUnloadSource = std::get<1>(m_onUnloadFunc);
             if(!onUnloadBuffer.empty()) {
                 g_lua.loadBuffer(onUnloadBuffer, onUnloadSource);
-                if(m_sandboxed) {
-                    g_lua.getRef(m_sandboxEnv);
-                    g_lua.setEnv();
-                }
                 g_lua.safeCall(0, 0);
             }
+
+            if(m_sandboxed)
+                g_lua.resetGlobalEnvironment();
         } catch(stdext::exception& e) {
+            if(m_sandboxed)
+                g_lua.resetGlobalEnvironment();
             g_logger.error(stdext::format("Unable to unload module '%s': %s", m_name, e.what()));
         }
 
+        // clear all env references
+        g_lua.getRef(m_sandboxEnv);
+        g_lua.clearTable();
+        g_lua.pop();
+
         m_loaded = false;
         //g_logger.info(stdext::format("Unloaded module '%s'", m_name));
         g_modules.updateModuleLoadOrder(asModule());
@@ -135,6 +147,12 @@ bool Module::hasDependency(const std::string& name)
     return false;
 }
 
+int Module::getSandbox(LuaInterface* lua)
+{
+    lua->getRef(m_sandboxEnv);
+    return 1;
+}
+
 void Module::discover(const OTMLNodePtr& moduleNode)
 {
     const static std::string none = "none";
diff --git a/src/framework/core/module.h b/src/framework/core/module.h
index 16250b0a..7ac37c31 100644
--- a/src/framework/core/module.h
+++ b/src/framework/core/module.h
@@ -43,7 +43,9 @@ public:
     bool isLoaded() { return m_loaded; }
     bool isReloadable() { return m_reloadable; }
     bool isDependent();
+    bool isSandboxed() { return m_sandboxed; }
     bool hasDependency(const std::string& name);
+    int getSandbox(LuaInterface *lua);
 
     std::string getDescription() { return m_description; }
     std::string getName() { return m_name; }
diff --git a/src/framework/core/resourcemanager.cpp b/src/framework/core/resourcemanager.cpp
index e94610fa..2dacba5e 100644
--- a/src/framework/core/resourcemanager.cpp
+++ b/src/framework/core/resourcemanager.cpp
@@ -151,7 +151,7 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
         PHYSFS_file* file = PHYSFS_openRead(fullPath.c_str());
         if(!file) {
             out.clear(std::ios::failbit);
-            stdext::throw_exception(stdext::format("failed to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
+            stdext::throw_exception(stdext::format("unable to load file '%s': %s", fullPath.c_str(), PHYSFS_getLastError()));
         } else {
             int fileSize = PHYSFS_fileLength(file);
             if(fileSize > 0) {
@@ -167,7 +167,7 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
         std::ifstream fin(fileName);
         if(!fin) {
             out.clear(std::ios::failbit);
-            stdext::throw_exception(stdext::format("failed to load file '%s': %s", fileName.c_str(), PHYSFS_getLastError()));
+            stdext::throw_exception(stdext::format("unable to file '%s': %s", fileName.c_str(), PHYSFS_getLastError()));
         } else {
             out << fin.rdbuf();
         }
diff --git a/src/framework/luaengine/luainterface.cpp b/src/framework/luaengine/luainterface.cpp
index db3c34e8..e2e0d80f 100644
--- a/src/framework/luaengine/luainterface.cpp
+++ b/src/framework/luaengine/luainterface.cpp
@@ -47,6 +47,12 @@ void LuaInterface::init()
 {
     createLuaState();
 
+    // store global environment reference
+    pushThread();
+    getEnv();
+    m_globalEnv = ref();
+    pop();
+
     // check if demangle_type is working as expected
     assert(stdext::demangle_type<LuaObject>() == "LuaObject");
 
@@ -297,7 +303,7 @@ bool LuaInterface::safeRunScript(const std::string& fileName)
     try {
         runScript(fileName);
         return true;
-    } catch(LuaException& e) {
+    } catch(stdext::exception& e) {
         g_logger.error(stdext::format("Failed to load script '%s': %s", fileName, e.what()));
         return false;
     }
@@ -322,13 +328,9 @@ void LuaInterface::loadScript(const std::string& fileName)
     if(!boost::starts_with(fileName, "/"))
         filePath = getCurrentSourcePath() + "/" + filePath;
 
-    try {
-        std::string buffer = g_resources.loadFile(fileName);
-        std::string source = "@" + filePath;
-        loadBuffer(buffer, source);
-    } catch(stdext::exception& e) {
-        throw LuaException(e.what());
-    }
+    std::string buffer = g_resources.loadFile(fileName);
+    std::string source = "@" + filePath;
+    loadBuffer(buffer, source);
 }
 
 void LuaInterface::loadFunction(const std::string& buffer, const std::string& source)
@@ -515,7 +517,7 @@ int LuaInterface::signalCall(int numArgs, int numRets)
         else {
             throw LuaException("attempt to call a non function value", 0);
         }
-    } catch(LuaException &e) {
+    } catch(stdext::exception& e) {
         g_logger.error(stdext::format("protected lua call failed: %s", e.what()));
     }
 
@@ -529,16 +531,16 @@ int LuaInterface::signalCall(int numArgs, int numRets)
     return rets;
 }
 
-void LuaInterface::newEnvironment()
+int LuaInterface::newSandboxEnv()
 {
     newTable(); // pushes the new environment table
     newTable(); // pushes the new environment metatable
-    getGlobalEnvironment();  // pushes the global environment
+    getRef(getGlobalEnvironment());  // pushes the global environment
     setField("__index"); // sets metatable __index to the global environment
     setMetatable(); // assigns environment metatable
+    return ref(); // return a reference to the environment table
 }
 
-
 ///////////////////////////////////////////////////////////////////////////////
 // lua C functions
 
@@ -550,13 +552,13 @@ int LuaInterface::luaScriptLoader(lua_State* L)
     try {
         g_lua.loadScript(fileName);
         return 1;
-    } catch(LuaException& e) {
-        g_logger.error(stdext::format("failed to load script file '%s': %s", fileName, e.what()));
-        return 0;
+    } catch(stdext::exception& e) {
+        g_lua.pushString(stdext::mkstr("\n\t", e.what()));
+        return 1;
     }
 }
 
-int LuaInterface::luaScriptRunner(lua_State* L)
+int LuaInterface::lua_dofile(lua_State* L)
 {
     std::string fileName = g_lua.popString();
     if(!boost::ends_with(fileName, ".lua"))
@@ -566,13 +568,14 @@ int LuaInterface::luaScriptRunner(lua_State* L)
         g_lua.loadScript(fileName);
         g_lua.call(0, LUA_MULTRET);
         return g_lua.stackSize();
-    } catch(LuaException& e) {
-        g_logger.error(stdext::format("failed to load script file '%s': %s", fileName, e.what()));
+    } catch(stdext::exception& e) {
+        g_lua.pushString(e.what());
+        g_lua.error();
         return 0;
     }
 }
 
-int LuaInterface::luaScriptsRunner(lua_State* L)
+int LuaInterface::lua_dofiles(lua_State* L)
 {
     std::string directory = g_lua.popString();
 
@@ -583,13 +586,31 @@ int LuaInterface::luaScriptsRunner(lua_State* L)
         try {
             g_lua.loadScript(directory + "/" + fileName);
             g_lua.call(0, 0);
-        } catch(LuaException& e) {
-            g_logger.error(stdext::format("failed to load script file '%s': %s", fileName, e.what()));
+        } catch(stdext::exception& e) {
+            g_lua.pushString(e.what());
+            g_lua.error();
         }
     }
     return 0;
 }
 
+int LuaInterface::lua_loadfile(lua_State* L)
+{
+    std::string fileName = g_lua.popString();
+    if(!boost::ends_with(fileName, ".lua"))
+        fileName += ".lua";
+
+    try {
+        g_lua.loadScript(fileName);
+        return 1;
+    } catch(stdext::exception& e) {
+        g_lua.pushNil();
+        g_lua.pushString(e.what());
+        g_lua.error();
+        return 2;
+    }
+}
+
 int LuaInterface::luaErrorHandler(lua_State* L)
 {
     // pops the error message
@@ -618,12 +639,13 @@ int LuaInterface::luaCppFunctionCallback(lua_State* L)
         numRets = (*(funcPtr->get()))(&g_lua);
         g_lua.m_cppCallbackDepth--;
         assert(numRets == g_lua.stackSize());
-    } catch(stdext::exception &e) {
+    } catch(stdext::exception& e) {
         // cleanup stack
         while(g_lua.stackSize() > 0)
             g_lua.pop();
         numRets = 0;
-        g_logger.error(stdext::format("C++ call failed: %s", g_lua.traceback(e.what())));
+        g_lua.pushString(stdext::format("C++ call failed: %s", g_lua.traceback(e.what())));
+        g_lua.error();
     }
 
     return numRets;
@@ -670,13 +692,24 @@ void LuaInterface::createLuaState()
     rawSeti(5);
     pop(2);
 
+    // replace loadfile
+    getGlobal("package");
+    getField("loaders");
+    pushCFunction(&LuaInterface::luaScriptLoader);
+    rawSeti(5);
+    pop(2);
+
     // replace dofile
-    pushCFunction(&LuaInterface::luaScriptRunner);
+    pushCFunction(&LuaInterface::lua_dofile);
     setGlobal("dofile");
 
     // dofiles
-    pushCFunction(&LuaInterface::luaScriptsRunner);
+    pushCFunction(&LuaInterface::lua_dofiles);
     setGlobal("dofiles");
+
+    // replace loadfile
+    pushCFunction(&LuaInterface::lua_loadfile);
+    setGlobal("loadfile");
 }
 
 void LuaInterface::closeLuaState()
@@ -833,18 +866,13 @@ void LuaInterface::getWeakRef(int weakRef)
     remove(-2);
 }
 
-void LuaInterface::getGlobalEnvironment()
+void LuaInterface::setGlobalEnvironment(int env)
 {
     pushThread();
-    getEnv();
-    remove(-2);
-}
-
-void LuaInterface::setGlobalEnvironment()
-{
-    pushThread();
-    insert(-2);
+    getRef(env);
+    assert(isTable());
     setEnv();
+    pop();
 }
 
 void LuaInterface::setMetatable(int index)
@@ -899,6 +927,24 @@ void LuaInterface::setTable(int index)
     lua_settable(L, index);
 }
 
+void LuaInterface::clearTable(int index)
+{
+    assert(hasIndex(index) && isTable(index));
+    pushNil();
+    bool stop = false;
+    while(!stop && next(index-1)) {
+        pop();
+        pushValue();
+        if(next(index-2))
+            pop();
+        else
+            stop = true;
+        insert(-2);
+        pushNil();
+        rawSet(index-3);
+    }
+}
+
 void LuaInterface::getGlobal(const std::string& key)
 {
     lua_getglobal(L, key.c_str());
diff --git a/src/framework/luaengine/luainterface.h b/src/framework/luaengine/luainterface.h
index 86175baa..eb2ce366 100644
--- a/src/framework/luaengine/luainterface.h
+++ b/src/framework/luaengine/luainterface.h
@@ -186,7 +186,7 @@ public:
     /// The new environment table is redirected to the global environment (aka _G),
     /// this allows to access global variables from _G in the new environment and
     /// prevents new variables in this new environment to be set on the global environment
-    void newEnvironment();
+    int newSandboxEnv();
 
     template<typename... T>
     int callGlobalField(const std::string& global, const std::string& field, const T&... args);
@@ -200,9 +200,11 @@ private:
     /// Load scripts requested by lua 'require'
     static int luaScriptLoader(lua_State* L);
     /// Run scripts requested by lua 'dofile'
-    static int luaScriptRunner(lua_State* L);
+    static int lua_dofile(lua_State* L);
     /// Run scripts requested by lua 'dofiles'
-    static int luaScriptsRunner(lua_State* L);
+    static int lua_dofiles(lua_State* L);
+    /// Run scripts requested by lua 'dofiles'
+    static int lua_loadfile(lua_State* L);
     /// Handle lua errors from safeCall
     static int luaErrorHandler(lua_State* L);
     /// Handle bound cpp functions callbacks
@@ -240,8 +242,9 @@ public:
     void getRef(int ref);
     void getWeakRef(int weakRef);
 
-    void getGlobalEnvironment();
-    void setGlobalEnvironment();
+    int getGlobalEnvironment() { return m_globalEnv; }
+    void setGlobalEnvironment(int env);
+    void resetGlobalEnvironment() { setGlobalEnvironment(m_globalEnv); }
 
     void setMetatable(int index = -2);
     void getMetatable(int index = -1);
@@ -253,6 +256,7 @@ public:
 
     void getTable(int index = -2);
     void setTable(int index = -3);
+    void clearTable(int index = -1);
 
     void getEnv(int index = -1);
     void setEnv(int index = -2);
@@ -334,6 +338,7 @@ private:
     int m_cppCallbackDepth;
     int m_totalObjRefs;
     int m_totalFuncRefs;
+    int m_globalEnv;
 };
 
 extern LuaInterface g_lua;
diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp
index 3251040c..a1191865 100644
--- a/src/framework/luafunctions.cpp
+++ b/src/framework/luafunctions.cpp
@@ -148,11 +148,13 @@ void Application::registerLuaFunctions()
     g_lua.bindClassMemberFunction<Module>("canUnload", &Module::canUnload);
     g_lua.bindClassMemberFunction<Module>("isLoaded", &Module::isLoaded);
     g_lua.bindClassMemberFunction<Module>("isReloadble", &Module::isReloadable);
+    g_lua.bindClassMemberFunction<Module>("isSandboxed", &Module::isSandboxed);
     g_lua.bindClassMemberFunction<Module>("getDescription", &Module::getDescription);
     g_lua.bindClassMemberFunction<Module>("getName", &Module::getName);
     g_lua.bindClassMemberFunction<Module>("getAuthor", &Module::getAuthor);
     g_lua.bindClassMemberFunction<Module>("getWebsite", &Module::getWebsite);
     g_lua.bindClassMemberFunction<Module>("getVersion", &Module::getVersion);
+    g_lua.bindClassMemberFunction<Module>("getSandbox", &Module::getSandbox);
     g_lua.bindClassMemberFunction<Module>("isAutoLoad", &Module::isAutoLoad);
     g_lua.bindClassMemberFunction<Module>("getAutoLoadPriority", &Module::getAutoLoadPriority);
 
diff --git a/src/framework/ui/uiwidgetbasestyle.cpp b/src/framework/ui/uiwidgetbasestyle.cpp
index 2126c624..cf9ea1ac 100644
--- a/src/framework/ui/uiwidgetbasestyle.cpp
+++ b/src/framework/ui/uiwidgetbasestyle.cpp
@@ -312,6 +312,7 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
         } else if(boost::starts_with(node->tag(), "&")) {
             std::string fieldName = node->tag().substr(1);
             std::string fieldOrigin = "@" + node->source() + "[" + node->tag() + "]";
+
             g_lua.evaluateExpression(node->value(), fieldOrigin);
             luaSetField(fieldName);
         }