diff --git a/files/docs/strictness/CHANGELOG.md b/files/docs/strictness/CHANGELOG.md
new file mode 100644
index 0000000..49d4365
--- /dev/null
+++ b/files/docs/strictness/CHANGELOG.md
@@ -0,0 +1,20 @@
+CHANGELOG
+=========
+
+###0.2.0 (06/11/14)
+* `strictness` no longer create globals. It returns a local table of library functions.
+* `strictness` can now create (or convert) strict/unstrict tables (or environnements).
+* Strict/unstrict rules are now applied per table (or environnement).
+* Strict mode enforces variable declarations and complain on undefined fields access/assignment.
+* Tables (or environnements) already existing metatables are preserved, including `__index` and `__newindex` fields.
+* Added `strictness.strict` to convert a normal table (or environnement) to a strict one.
+* Added `strictness.unstrict` to convert a strict table (or environnement) to a normal one.
+* Added `strictness.is_strict` to check if a table (or environnement) is strict.
+* Added `strictness.strictf` to wrap a normal function into a non strict function.
+* Added `strictness.unstrictf` to wrap a normal function into a strict function.
+* Added `strictness.run_strict` to run a normal function in strict mode.
+* Added `strictness.run_unstrict` to run a normal function in non strict mode.
+* Made compliant with Lua 5.2 new _ENV lexical scoping (although strictly speaking there are no globals in Lua 5.2).
+
+###0.1.0 (10/05/13)
+* Initial release
\ No newline at end of file
diff --git a/files/docs/strictness/LICENSE b/files/docs/strictness/LICENSE
new file mode 100644
index 0000000..8ba7b05
--- /dev/null
+++ b/files/docs/strictness/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2014 Roland Y.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/files/docs/strictness/README.md b/files/docs/strictness/README.md
new file mode 100644
index 0000000..1f7ed5f
--- /dev/null
+++ b/files/docs/strictness/README.md
@@ -0,0 +1,63 @@
+strictness
+===========
+
+[![Build Status](https://travis-ci.org/Yonaba/strictness.png)](https://travis-ci.org/Yonaba/strictness)
+[![Coverage Status](https://coveralls.io/repos/Yonaba/strictness/badge.png?branch=master)](https://coveralls.io/r/Yonaba/strictness?branch=master)
+[![License](http://img.shields.io/badge/Licence-MIT-brightgreen.svg)](LICENSE)
+
+With the __Lua__ programming language, undeclared variables are not detected until runtime, as Lua will not complain when loading code.
+This is releated to the convention that Lua uses : [global by default](http://www.lua.org/pil/1.2.html). In other words, when a variable is not recognized as *local*, it will be
+interpreted as a *global* one, and will involve a lookup in the global environment `_G` (for Lua 5.1). Note that this behaviour has been addressed
+in Lua 5.2, which strictly speaking has no globals, because of its [lexical scoping](http://www.luafaq.org/#T8.2.1).
+
+*strictness* is a module to track *access and assignment* to undefined variables in your code. It *enforces* to declare globals and modules variables before
+assigning them values. As such, it helps having a better control on the scope of variables across the code.
+
+*strictness* is mostly meant to work with Lua [5.1](http://www.lua.org/versions.html#5.1), but it is compatible with Lua [5.2](http://www.lua.org/versions.html#5.2).
+
+##Installation
+
+####Git
+
+ git clone git://github.com/Yonaba/strictness
+
+####Download
+
+* See [releases](https://github.com/Yonaba/strictness/releases)
+
+####LuaRocks
+
+ luarocks install strictness
+
+####MoonRocks
+
+ moonrocks install strictness
+
+or
+
+ luarocks install strictness --server=http://rocks.moonscript.org strictness
+
+
+## Documentation
+
+See [tutorial.md](doc/tutorial.md).
+
+##Tests
+
+This project has specification tests. To run these tests, execute the following command from the project root folder:
+
+ lua spec/tests.lua
+
+##Similar projects
+
+Feel free to check those alternate implementations, from with *strictness* takes some inspiration:
+
+* [strict.lua](http://rtfc.googlecode.com/svn-history/r2/trunk/lua-5.1/etc/strict.lua) which is included in the official Lua 5.1 distribution,
+* [pl.strict](https://github.com/stevedonovan/Penlight/blob/master/lua/pl/strict.lua) which is part of [Penlight](https://github.com/stevedonovan/Penlight),
+
+##License
+This work is under [MIT-LICENSE](http://www.opensource.org/licenses/mit-license.php)
+*Copyright (c) 2013-2014 Roland Yonaba*.
+See [LICENSE](LICENSE).
+
+[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/Yonaba/strictness/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
\ No newline at end of file
diff --git a/files/docs/strictness/html/index.html b/files/docs/strictness/html/index.html
new file mode 100644
index 0000000..fe1c75a
--- /dev/null
+++ b/files/docs/strictness/html/index.html
@@ -0,0 +1,306 @@
+
+
+
+
Returns the result of a function call in non-strict mode.
+
+
+
+
+
+
+
+
Functions
+
+
+
+
+ strict ([t[, ...]])
+
+
+ Makes a given table strict. It mutates the passed-in table (or creates a
+ new table) and returns it. The returned table is strict, indexing or
+ assigning undefined fields will raise an error.
+
+
+
Parameters:
+
+
t
+ a table
+
+
...
+ a vararg list of allowed fields in the table.
+
+
+
+
Returns:
+
+
+ the passed-in table t or a new table, patched to be strict.
+
+
+
+
+
Usage:
+
+
+ local t = strictness.strict()
+ local t2 = strictness.strict({})
+ local t3 = strictness.strict({}, 'field1', 'field2')
+
+
+
+
+
+ is_strict (t)
+
+
+ Checks if a given table is strict.
+
+
+
Parameters:
+
+
t
+ a table
+
+
+
+
Returns:
+
+
+ true if the table is strict, false otherwise.
+
+
+
+
+
Usage:
+
+
local is_strict = strictness.is_strict(a_table)
+
+
+
+
+
+ unstrict (t)
+
+
+ Makes a given table non-strict. It mutates the passed-in table and
+ returns it. The returned table is non-strict.
+
+
+
Parameters:
+
+
t
+ a table
+
+
+
+
+
+
+
Usage:
+
+
local unstrict_table = strictness.unstrict(trict_table)
+
+
+
+
+
+ strictf (f)
+
+
+ Creates a strict function. Wraps the given function and returns the wrapper.
+ The new function will always run in strict mode in its environment, whether
+ or not this environment is strict.
+
+
+
Parameters:
+
+
f
+ a function, or a callable value.
+
+
+
+
+
+
+
Usage:
+
+
+ local strict_f = strictness.strictf(a_function)
+ local result = strict_f(...)
+
+
+
+
+
+ unstrictf (f)
+
+
+ Creates a non-strict function. Wraps the given function and returns the wrapper.
+ The new function will always run in non-strict mode in its environment, whether
+ or not this environment is strict.
+
+
+
Parameters:
+
+
f
+ a function, or a callable value.
+
+
+
+
+
+
+
Usage:
+
+
+ local unstrict_f = strictness.unstrictf(a_function)
+ local result = unstrict_f(...)
+
+
+
+
+
+ run_strict (f[, ...])
+
+
+ Returns the result of a function call in strict mode.
+
+
+
Parameters:
+
+
f
+ a function, or a callable value.
+
+
...
+ a vararg list of arguments to function f.
+
+
+
+
+
+
+
Usage:
+
+
local result = strictness.run_strict(a_function, arg1, arg2)
+
+
+
+
+
+ run_unstrict (f[, ...])
+
+
+ Returns the result of a function call in non-strict mode.
+
+
+
Parameters:
+
+
f
+ a function, or a callable value.
+
+
...
+ a vararg list of arguments to function f.
+
+
+
+
+
+
+
Usage:
+
+
local result = strictness.run_unstrict(a_function, arg1, arg2)
+
+
diff --git a/files/docs/strictness/html/ldoc.css b/files/docs/strictness/html/ldoc.css
new file mode 100644
index 0000000..765c710
--- /dev/null
+++ b/files/docs/strictness/html/ldoc.css
@@ -0,0 +1,302 @@
+/* BEGIN RESET
+
+Copyright (c) 2010, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.8.2r1
+*/
+html {
+ color: #000;
+ background: #FFF;
+}
+body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td {
+ margin: 0;
+ padding: 0;
+}
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+fieldset,img {
+ border: 0;
+}
+address,caption,cite,code,dfn,em,strong,th,var,optgroup {
+ font-style: inherit;
+ font-weight: inherit;
+}
+del,ins {
+ text-decoration: none;
+}
+li {
+ list-style: disc;
+ margin-left: 20px;
+}
+caption,th {
+ text-align: left;
+}
+h1,h2,h3,h4,h5,h6 {
+ font-size: 100%;
+ font-weight: bold;
+}
+q:before,q:after {
+ content: '';
+}
+abbr,acronym {
+ border: 0;
+ font-variant: normal;
+}
+sup {
+ vertical-align: baseline;
+}
+sub {
+ vertical-align: baseline;
+}
+legend {
+ color: #000;
+}
+input,button,textarea,select,optgroup,option {
+ font-family: inherit;
+ font-size: inherit;
+ font-style: inherit;
+ font-weight: inherit;
+}
+input,button,textarea,select {*font-size:100%;
+}
+/* END RESET */
+
+body {
+ margin-left: 1em;
+ margin-right: 1em;
+ font-family: arial, helvetica, geneva, sans-serif;
+ background-color: #ffffff; margin: 0px;
+}
+
+code, tt { font-family: monospace; }
+span.parameter { font-family:monospace; }
+span.parameter:after { content:":"; }
+span.types:before { content:"("; }
+span.types:after { content:")"; }
+.type { font-weight: bold; font-style:italic }
+
+body, p, td, th { font-size: .95em; line-height: 1.2em;}
+
+p, ul { margin: 10px 0 0 0px;}
+
+strong { font-weight: bold;}
+
+em { font-style: italic;}
+
+h1 {
+ font-size: 1.5em;
+ margin: 0 0 20px 0;
+}
+h2, h3, h4 { margin: 15px 0 10px 0; }
+h2 { font-size: 1.25em; }
+h3 { font-size: 1.15em; }
+h4 { font-size: 1.06em; }
+
+a:link { font-weight: bold; color: #004080; text-decoration: none; }
+a:visited { font-weight: bold; color: #006699; text-decoration: none; }
+a:link:hover { text-decoration: underline; }
+
+hr {
+ color:#cccccc;
+ background: #00007f;
+ height: 1px;
+}
+
+blockquote { margin-left: 3em; }
+
+ul { list-style-type: disc; }
+
+p.name {
+ font-family: "Andale Mono", monospace;
+ padding-top: 1em;
+}
+
+pre.example {
+ background-color: rgb(245, 245, 245);
+ border: 1px solid silver;
+ padding: 10px;
+ margin: 10px 0 10px 0;
+ font-family: "Andale Mono", monospace;
+ font-size: .85em;
+}
+
+pre {
+ background-color: rgb(245, 245, 245);
+ border: 1px solid silver;
+ padding: 10px;
+ margin: 10px 0 10px 0;
+ overflow: auto;
+ font-family: "Andale Mono", monospace;
+}
+
+
+table.index { border: 1px #00007f; }
+table.index td { text-align: left; vertical-align: top; }
+
+#container {
+ margin-left: 1em;
+ margin-right: 1em;
+ background-color: #f0f0f0;
+}
+
+#product {
+ text-align: center;
+ border-bottom: 1px solid #cccccc;
+ background-color: #ffffff;
+}
+
+#product big {
+ font-size: 2em;
+}
+
+#main {
+ background-color: #f0f0f0;
+ border-left: 2px solid #cccccc;
+}
+
+#navigation {
+ float: left;
+ width: 18em;
+ vertical-align: top;
+ background-color: #f0f0f0;
+ overflow: visible;
+}
+
+#navigation h2 {
+ background-color:#e7e7e7;
+ font-size:1.1em;
+ color:#000000;
+ text-align: left;
+ padding:0.2em;
+ border-top:1px solid #dddddd;
+ border-bottom:1px solid #dddddd;
+}
+
+#navigation ul
+{
+ font-size:1em;
+ list-style-type: none;
+ margin: 1px 1px 10px 1px;
+}
+
+#navigation li {
+ text-indent: -1em;
+ display: block;
+ margin: 3px 0px 0px 22px;
+}
+
+#navigation li li a {
+ margin: 0px 3px 0px -1em;
+}
+
+#content {
+ margin-left: 18em;
+ padding: 1em;
+ width: 700px;
+ border-left: 2px solid #cccccc;
+ border-right: 2px solid #cccccc;
+ background-color: #ffffff;
+}
+
+#about {
+ clear: both;
+ padding: 5px;
+ border-top: 2px solid #cccccc;
+ background-color: #ffffff;
+}
+
+@media print {
+ body {
+ font: 12pt "Times New Roman", "TimeNR", Times, serif;
+ }
+ a { font-weight: bold; color: #004080; text-decoration: underline; }
+
+ #main {
+ background-color: #ffffff;
+ border-left: 0px;
+ }
+
+ #container {
+ margin-left: 2%;
+ margin-right: 2%;
+ background-color: #ffffff;
+ }
+
+ #content {
+ padding: 1em;
+ background-color: #ffffff;
+ }
+
+ #navigation {
+ display: none;
+ }
+ pre.example {
+ font-family: "Andale Mono", monospace;
+ font-size: 10pt;
+ page-break-inside: avoid;
+ }
+}
+
+table.module_list {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #cccccc;
+ border-collapse: collapse;
+}
+table.module_list td {
+ border-width: 1px;
+ padding: 3px;
+ border-style: solid;
+ border-color: #cccccc;
+}
+table.module_list td.name { background-color: #f0f0f0; min-width: 200px; }
+table.module_list td.summary { width: 100%; }
+
+
+table.function_list {
+ border-width: 1px;
+ border-style: solid;
+ border-color: #cccccc;
+ border-collapse: collapse;
+}
+table.function_list td {
+ border-width: 1px;
+ padding: 3px;
+ border-style: solid;
+ border-color: #cccccc;
+}
+table.function_list td.name { background-color: #f0f0f0; min-width: 200px; }
+table.function_list td.summary { width: 100%; }
+
+ul.nowrap {
+ overflow:auto;
+ white-space:nowrap;
+}
+
+dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
+dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;}
+dl.table h3, dl.function h3 {font-size: .95em;}
+
+/* stop sublists from having initial vertical space */
+ul ul { margin-top: 0px; }
+ol ul { margin-top: 0px; }
+ol ol { margin-top: 0px; }
+ul ol { margin-top: 0px; }
+
+/* styles for prettification of source */
+pre .comment { color: #558817; }
+pre .constant { color: #a8660d; }
+pre .escape { color: #844631; }
+pre .keyword { color: #2239a8; font-weight: bold; }
+pre .library { color: #0e7c6b; }
+pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; }
+pre .string { color: #a8660d; }
+pre .number { color: #f8660d; }
+pre .operator { color: #2239a8; font-weight: bold; }
+pre .preprocessor, pre .prepro { color: #a33243; }
+pre .global { color: #800080; }
+pre .prompt { color: #558817; }
+pre .url { color: #272fc2; text-decoration: underline; }
diff --git a/files/docs/strictness/tutorial.md b/files/docs/strictness/tutorial.md
new file mode 100644
index 0000000..b80eaeb
--- /dev/null
+++ b/files/docs/strictness/tutorial.md
@@ -0,0 +1,277 @@
+strictness tutorial
+===================
+
+# Table of Contents
+
+* [What is *strictness* ?](#what)
+* [Tutorial](#tuto)
+ * [Adding *strictness* to your project](#adding)
+ * [The *strictness* module](#module)
+ * [Strict tables](#stricttables)
+ * [Non-strict tables](#unstricttables)
+ * [Checking strictness](#checking)
+ * [Strict functions](#strictf)
+ * [Non-strict functions](#unstrictf)
+ * [Combo functions](#combo)
+* [License](#license)
+
+# What is *strictness* ?
+
+*strictness* is a Lua module for tracking accesses and assignements to indefined variables in Lua code. It is actually known that [undefined variables](http://lua-users.org/wiki/DetectingUndefinedVariables) and global variables as well can be very problematic especially when working on large projects and maintaining code that spans across several files.
+
+*strictness* aims to address this problem by providing a solution similar to [strict structs](http://lua-users.org/wiki/StrictStructs), so that accessing undefined fields will always throw an error.
+
+**[[⬆]](#TOC)**
+
+# Tutorial
+
+## Adding *strictness* to your project
+
+Place the file [strictness.lua](strictness.lua) in your Lua project and call it with [require](http://pgl.yoyo.org/luai/i/require). *strictness* does not write anything in the global (or the current) environnement. It rather returns a local module of functions.
+
+```lua
+local strictness = require "strictness"
+````
+
+**[[⬆]](#TOC)**
+
+## The *strictness* module
+
+### Strict tables
+
+*strictness* provides the function `strictness.strict` that patches a given table, so that we can no longer access to undefined keys in this table.
+Let us apply appy this on the global environnement:
+
+```lua
+strictness.strict(_G)
+print(x) --> this line produces an error
+````
+
+The statement `print(x)`produces the following error:
+
+````
+...\test.lua:2: Attempt to access undeclared variable "x" in .
+```
+
+To avoid this, we now have to __declare explitely__ our globals. Assigning `nil` will do:
+
+```lua
+strictness.strict(_G)
+x = nil
+print(x) --> nil
+x = 3
+print(x) --> 3
+````
+
+A table can be made strict with allowed varnames.
+
+```lua
+strictness.strict(_G, 'x', 'y', 'z') -- "varnames x, y and z are allowed"
+print(x, y, z) --> nil, nil, nil
+x, y, z = 1, 2, 3
+print(x, y, z) --> 1, 2, 3
+````
+
+Also, in case nothing is passed to `strictness.strict`, it will return a new table:
+
+```lua
+local t = strictness.strict()
+print(t.k) --> produces an error
+t.k = nil --> declare a field "k"
+print(t.k) --> nil
+````
+
+`strictness.strict` preserves the metatable of the passed-in table.
+
+```lua
+local t = setmetatable({}, {
+ __call = function() return 'call' end,
+ __tostring = function() return t.name end
+})
+t.name = 'table t'
+strictness.strict(t)
+print(t()) --> "call"
+print(t) --> "table t"
+````
+
+In case a table was already made strict, passing it again to `strictness.strict` will raise an error:
+
+```lua
+local t = {}
+strictness.strict(t)
+strictness.strict(t) --> this will produce an error
+````
+
+````
+...\test.lua:3: was already made strict.
+````
+
+**[[⬆]](#TOC)**
+
+### Non-Strict (or normal) tables
+
+A strict table can be converted back to a normal one via `strictness.unstrict`:
+
+```lua
+local t = strictness.strict()
+strictness.unstrict(t)
+t.k = 5
+print(t.k) --> 5
+````
+
+**[[⬆]](#TOC)**
+
+### Checking strictness
+
+`strictness.is_strict` checks if a given table was patched via `strictness.strict`:
+
+```lua
+local strict_table = strictness.strict()
+local normal_table = {}
+
+print(strictness.is_strict(strict_table)) --> true
+print(strictness.is_strict(normal_table)) --> false
+````
+
+**[[⬆]](#TOC)**
+
+### Strict functions
+
+`strictness.strictf` returns a wrapper function that runs the original function in strict mode. The returned function is not allowed to write or access undefined fields in its environment. Let us draw an example:
+
+```lua
+local env = {} -- a blank environment for our functions
+
+-- A function that writes a varname and assigns it a value
+local function normal_f(varname, value)
+ env[varname] = value
+end
+-- Convert the original function to a strict one
+local strict_f = strictness.strictf(normal_f)
+
+-- set environments for functions
+setfenv(normal_f, env)
+setfenv(strict_f, env)
+
+-- Call the normal function, no error
+normal_f("var1", "hello")
+print(env.var1) --> "hello"
+
+
+strict_f("var2", "hello") --> produces an error
+````
+
+````
+...\test.lua:5: Attempt to assign value to an undeclared variable "var2" in .
+````
+
+Notice that here, the strict function always run in strict mode whether its environment is strict or not.
+
+**[[⬆]](#TOC)**
+
+### Non-strict functions
+
+Similarly, `strictness.unstrictf` creates a wrapper function that runs in non-strict mode in its environment. In other terms, the returned function is allowed to access and assign values in its environments, whether or not this environment is strict.
+
+```lua
+local env = strictness.strict() -- a blank and strict environment for our functions
+
+-- A function that assigns a value to a variable named "some_var"
+local function normal_f(value)
+ some_var = value
+end
+
+-- Converts the original function to a non-strict one
+local unstrict_f = strictness.unstrictf(normal_f)
+
+-- set environments for functions
+setfenv(normal_f, env)
+setfenv(unstrict_f, env)
+
+-- Call the normal function, it should err because its env is strict
+normal_f("hello") --> produces an error
+
+-- Call the non-strict function, no error
+unstrict_f("hello")
+print(env.some_var) --> "hello
+````
+
+Here is an example with Lua 5.2:
+
+```lua
+local new_env = {print = print} -- a new env
+do
+ local _ENV = strictness.strict(new_env) -- sets a new strict env for the do..end scope
+ local function normal_f(value) some_var = value end -- our normal function
+ normal_f(5) --> produces an error, since normal_f cannot write in the strict _ENV
+end
+````
+
+```lua
+local new_env = {print = print} -- a new env
+do
+ local _ENV = strictness.strict(new_env) -- sets a new strict env for the do..end scope
+ local function normal_f(value) some_var = value end -- our normal function
+ local unstrict_f = strictness.unstrictf(normal_f) -- the non-strict version of our normal function
+ unstrict_f(5) -- no longer produces error
+ print(some_var) --> 5
+end
+````
+
+**[[⬆]](#TOC)**
+
+### Combo functions
+
+*strictness* also provides two combo functions, `strictness.run_strict` and `strictness.run_unstrict`. Those functions takes a function `f` plus an optional vararg `...` and return the result of the call `f(...)` in strict and non-strict mode respectively.
+Syntactically speaking, `strictnes.run_strict` is the equivalent to this:
+
+```lua
+local strict_f = strictness.strictf(f)
+strict_f(...)
+````
+
+While `strictness.run_unstrict` is a short for:
+
+```lua
+local unstrict_f = strictness.unstrictf(f)
+unstrict_f(...)
+````
+
+Here is an example for `strictness.run_strict`:
+
+```lua
+local strictness = require 'strictness'
+
+local env = {} -- an environment
+
+-- A function that assigns a value to a variable named "some_var"
+local function normal_f(value) some_var = value end
+
+setfenv(normal_f, env) -- defines an env for normal_f
+strictness.run_strict(normal_f, 3) --> produces an error
+````
+
+And another example with `strictness.run_unstrict``:
+
+```lua
+local strictness = require 'strictness'
+
+local env = strictness.strict() -- a strict environment
+
+-- A function that assigns a value to a variable named "some_var"
+local function normal_f(value) some_var = value end
+
+setfenv(normal_f, env) -- defines an env for normal_f
+strictness.run_unstrict`(normal_f, 3) -- no error!
+print(env.some_var, some_var) --> 3, nil
+````
+
+**[[⬆]](#TOC)**
+
+# LICENSE
+
+This work is under [MIT-LICENSE](http://www.opensource.org/licenses/mit-license.php)
+*Copyright (c) 2013-2014 Roland Yonaba*.
+See [LICENSE](http://github.com/Yonaba/strictness/blob/master/LICENSE).
+
+**[[⬆]](#TOC)**
\ No newline at end of file
diff --git a/files/lua/strictness.lua b/files/lua/strictness.lua
new file mode 100644
index 0000000..a1912a9
--- /dev/null
+++ b/files/lua/strictness.lua
@@ -0,0 +1,259 @@
+#!/usr/bin/env lua
+------------------
+-- *strictness, a "strict" mode for Lua*.
+-- Source on [Github](http://github.com/Yonaba/strictness)
+-- @author Roland Yonaba
+-- @copyright 2013-2014
+-- @license MIT
+
+local _LUA52 = _VERSION:match('Lua 5.2')
+local setmetatable, getmetatable = setmetatable, getmetatable
+local pairs, ipairs = pairs, ipairs
+local rawget, rawget = rawget, rawget
+local unpack = _LUA52 and table.unpack or unpack
+local tostring, select, error = tostring, select, error
+local getfenv = getfenv
+
+local _MODULEVERSION = '0.2.0'
+
+----------------------------- Private definitions -----------------------------
+
+if _LUA52 then
+ -- Provide a replacement for getfenv in Lua 5.2, using the debug library
+ -- Taken from: http://lua-users.org/lists/lua-l/2010-06/msg00313.html
+ -- Slightly modified to handle f being nil and return _ENV if f is global.
+ getfenv = function(f)
+ f = (type(f) == 'function' and f or debug.getinfo((f or 0) + 1, 'f').func)
+ local name, val
+ local up = 0
+ repeat
+ up = up + 1
+ name, val = debug.getupvalue(f, up)
+ until name == '_ENV' or name == nil
+ return val~=nil and val or _ENV
+ end
+end
+
+-- Lua reserved keywords
+local is_reserved_keyword = {
+ ['and'] = true, ['break'] = true, ['do'] = true, ['else'] = true,
+ ['elseif'] = true, ['end'] = true, ['false'] = true, ['for'] = true,
+ ['function'] = true, ['if'] = true, ['in'] = true, ['local'] = true,
+ ['nil'] = true, ['not'] = true, ['or'] = true, ['repeat'] = true,
+ ['return'] = true, ['then'] = true, ['true'] = true, ['until'] = true,
+ ['while'] = true,
+}; if _LUA52 then is_reserved_keyword['goto'] = true end
+
+-- Throws an error if cond
+local function complain_if(cond, msg, level)
+ return cond and error(msg, level or 3)
+end
+
+-- Checks if iden match an valid Lua identifier syntax
+local function is_identifier(iden)
+ return tostring(iden):match('^[%a_]+[%w_]*$') and
+ not is_reserved_keyword[iden]
+end
+
+-- Checks if all elements of vararg are valid Lua identifiers
+local function validate_identifiers(...)
+ local arg, varnames= {...}, {}
+ for i, iden in ipairs(arg) do
+ complain_if(not is_identifier(iden),
+ ('varname #%d "<%s>" is not a valid Lua identifier.')
+ :format(i, tostring(iden)),4)
+ varnames[iden] = true
+ end
+ return varnames
+end
+
+-- add true keys in register all keys in t
+local function add_allowed_keys(t,register)
+ for key in pairs(t) do
+ if is_identifier(key) then register[key] = true end
+ end
+ return register
+end
+
+-- Checks if the given arg is callable
+local function callable(f)
+ return type(f) == 'function' or (getmetatable(f) and getmetatable(f).__call)
+end
+
+------------------------------- Module functions ------------------------------
+
+--- Makes a given table strict. It mutates the passed-in table (or creates a
+-- new table) and returns it. The returned table is strict, indexing or
+-- assigning undefined fields will raise an error.
+-- @function strictness.strict
+-- @param[opt] t a table
+-- @param[opt] ... a vararg list of allowed fields in the table.
+-- @return the passed-in table `t` or a new table, patched to be strict.
+-- @usage
+-- local t = strictness.strict()
+-- local t2 = strictness.strict({})
+-- local t3 = strictness.strict({}, 'field1', 'field2')
+local function make_table_strict(t, ...)
+ t = t or {}
+ local has_mt = getmetatable(t)
+ complain_if(type(t) ~= 'table',
+ ('Argument #1 should be a table, not %s.'):format(type(t)),3)
+ local mt = getmetatable(t) or {}
+ complain_if(mt.__strict,
+ ('<%s> was already made strict.'):format(tostring(t)),3)
+
+ local varnames = v
+ mt.__allowed = add_allowed_keys(t, validate_identifiers(...))
+ mt.__predefined_index = mt.__index
+ mt.__predefined_newindex = mt.__newindex
+
+ mt.__index = function(tbl, key)
+ if not mt.__allowed[key] then
+ if mt.__predefined_index then
+ local expected_result = mt.__predefined_index(tbl, key)
+ if expected_result then return expected_result end
+ end
+ complain_if(true,
+ ('Attempt to access undeclared variable "%s" in <%s>.')
+ :format(key, tostring(tbl)),3)
+ end
+ return rawget(tbl, key)
+ end
+
+ mt.__newindex = function(tbl, key, val)
+ if mt.__predefined_newindex then
+ mt.__predefined_newindex(tbl, key, val)
+ if rawget(tbl, key) ~= nil then return end
+ end
+ if not mt.__allowed[key] then
+ if val == nil then
+ mt.__allowed[key] = true
+ return
+ end
+ complain_if(not mt.__allowed[key],
+ ('Attempt to assign value to an undeclared variable "%s" in <%s>.')
+ :format(key,tostring(tbl)),3)
+ mt.__allowed[key] = true
+ end
+ rawset(tbl, key, val)
+ end
+
+ mt.__strict = true
+ mt.__has_mt = has_mt
+ return setmetatable(t, mt)
+
+end
+
+--- Checks if a given table is strict.
+-- @function strictness.is_strict
+-- @param t a table
+-- @return `true` if the table is strict, `false` otherwise.
+-- @usage
+-- local is_strict = strictness.is_strict(a_table)
+local function is_table_strict(t)
+ complain_if(type(t) ~= 'table',
+ ('Argument #1 should be a table, not %s.'):format(type(t)),3)
+ return not not (getmetatable(t) and getmetatable(t).__strict)
+end
+
+--- Makes a given table non-strict. It mutates the passed-in table and
+-- returns it. The returned table is non-strict.
+-- @function strictness.unstrict
+-- @param t a table
+-- @usage
+-- local unstrict_table = strictness.unstrict(trict_table)
+local function make_table_unstrict(t)
+ complain_if(type(t) ~= 'table',
+ ('Argument #1 should be a table, not %s.'):format(type(t)),3)
+ if is_table_strict(t) then
+ local mt = getmetatable(t)
+ if not mt.__has_mt then
+ setmetatable(t, nil)
+ else
+ mt.__index, mt.__newindex = mt.__predefined_index, mt.__predefined_newindex
+ mt.__strict, mt.__allowed, mt.__has_mt = nil, nil, nil
+ mt.__predefined_index, mt.__predefined_newindex = nil, nil
+ end
+ end
+ return t
+end
+
+--- Creates a strict function. Wraps the given function and returns the wrapper.
+-- The new function will always run in strict mode in its environment, whether
+-- or not this environment is strict.
+-- @function strictness.strictf
+-- @param f a function, or a callable value.
+-- @usage
+-- local strict_f = strictness.strictf(a_function)
+-- local result = strict_f(...)
+local function make_function_strict(f)
+ complain_if(not callable(f),
+ ('Argument #1 should be a callable, not %s.'):format(type(f)),3)
+ return function(...)
+ local ENV = getfenv(f)
+ local was_strict = is_table_strict(ENV)
+ if not was_strict then make_table_strict(ENV) end
+ local results = {f(...)}
+ if not was_strict then make_table_unstrict(ENV) end
+ return unpack(results)
+ end
+end
+
+--- Creates a non-strict function. Wraps the given function and returns the wrapper.
+-- The new function will always run in non-strict mode in its environment, whether
+-- or not this environment is strict.
+-- @function strictness.unstrictf
+-- @param f a function, or a callable value.
+-- @usage
+-- local unstrict_f = strictness.unstrictf(a_function)
+-- local result = unstrict_f(...)
+local function make_function_unstrict(f)
+ complain_if(not callable(f),
+ ('Argument #1 should be a callable, not %s.'):format(type(f)),3)
+ return function(...)
+ local ENV = getfenv(f)
+ local was_strict = is_table_strict(ENV)
+ make_table_unstrict(ENV)
+ local results = {f(...)}
+ if was_strict then make_table_strict(ENV) end
+ return unpack(results)
+ end
+end
+
+--- Returns the result of a function call in strict mode.
+-- @function strictness.run_strict
+-- @param f a function, or a callable value.
+-- @param[opt] ... a vararg list of arguments to function `f`.
+-- @usage
+-- local result = strictness.run_strict(a_function, arg1, arg2)
+local function run_strict(f,...)
+ complain_if(not callable(f),
+ ('Argument #1 should be a callable, not %s.'):format(type(f)),3)
+ return make_function_strict(f)(...)
+end
+
+--- Returns the result of a function call in non-strict mode.
+-- @function strictness.run_unstrict
+-- @param f a function, or a callable value.
+-- @param[opt] ... a vararg list of arguments to function `f`.
+-- @usage
+-- local result = strictness.run_unstrict(a_function, arg1, arg2)
+local function run_unstrict(f,...)
+ complain_if(not callable(f),
+ ('Argument #1 should be a callable, not %s.'):format(type(f)),3)
+ return make_function_unstrict(f)(...)
+end
+
+return {
+ strict = make_table_strict,
+ unstrict = make_table_unstrict,
+ is_strict = is_table_strict,
+ strictf = make_function_strict,
+ unstrictf = make_function_unstrict,
+ run_strict = run_strict,
+ run_unstrict = run_unstrict,
+ _VERSION = 'strictness v'.._MODULEVERSION,
+ _URL = 'http://github.com/Yonaba/strictness',
+ _LICENSE = 'MIT ',
+ _DESCRIPTION = 'Tracking accesses and assignments to undefined variables in Lua code'
+}
\ No newline at end of file