Project import
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..277b66f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,88 @@
+#
+#    Copyright (c) 2010-2011 Nest, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#    This Makefile is used to build luajson, a JSON parser written in lua
+#
+
+.NOTPARALLEL:
+
+BuildConfigSpecialized	:= No
+BuildProductSpecialized	:= No
+
+include pre.mak
+
+PackageName		:= luajson
+
+PackageExtension	:= tar.bz2
+PackageSeparator	:= -
+
+PackageArchive		:= $(PackageName).$(PackageExtension)
+PackageSourceDir	:= $(PackageName)$(PackageSeparator)$(PackageVersion)
+
+PackageBuildMakefile	= $(call GenerateBuildPaths,Makefile)
+
+CleanPaths		+= $(PackageLicenseFile)
+
+all: $(PackageDefaultGoal)
+
+# Generate the package license contents.
+
+$(PackageSourceDir)/LICENSE: source
+
+$(PackageLicenseFile): $(PackageSourceDir)/LICENSE
+	$(copy-result)
+
+# Extract the source from the archive and apply patches, if any.
+
+$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths)
+	$(expand-and-patch-package)
+
+# Prepare the sources.
+
+.PHONY: source
+source: | ${PackageSourceDir}
+
+# Patch the sources, if necessary.
+
+.PHONY: patch
+patch: source
+
+# Generate the package build makefile.
+
+$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory)
+	$(call create-links,$(CURDIR)/$(PackageSourceDir),$(BuildDirectory))
+
+# Configure the source for building.
+
+.PHONY: configure
+configure: patch | ${PackageBuildMakefile}
+
+.PHONY: build
+build: configure | $(BuildDirectory)
+
+
+# Stage the build to a temporary installation area.
+#
+# We have to unset MAKEFLAGS since they confuse the package build otherwise.
+.PHONY filestocopy:
+	cp -r ${call Slashify,${CURDIR}}${call Slashify,${PackageSourceDir}}lua ${ResultDirectory}
+
+
+.PHONY: stage
+stage: build filestocopy | $(ResultDirectory)
+
+clean:
+	$(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
+
+include post.mak
diff --git a/luajson-1.2.1/LICENSE b/luajson-1.2.1/LICENSE
new file mode 100644
index 0000000..f12cb56
--- /dev/null
+++ b/luajson-1.2.1/LICENSE
@@ -0,0 +1,27 @@
+The following license is applied to all documents in this project with the
+exception of the 'tests' directory at the root.
+The 'tests' directory is dual-licenses Public Domain / MIT, whichever is
+least restrictive in your legal jurisdiction.
+
+The MIT License
+
+Copyright (c) 2008 Thomas Harning Jr. <harningt@gmail.com>
+
+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/luajson-1.2.1/Makefile b/luajson-1.2.1/Makefile
new file mode 100644
index 0000000..b21d5f6
--- /dev/null
+++ b/luajson-1.2.1/Makefile
@@ -0,0 +1,45 @@
+#
+# Makefile to prepare releases and run tests
+#
+
+.PHONY: all clean check dist dist-all dist-bzip2 dist-gzip dist-zip distcheck
+
+DIST_DIR=dist
+LUA_BIN=lua
+
+
+all:
+	@echo Building nothing - no binaries
+
+clean:
+	@echo Cleaning nothing - no binaries
+
+
+dist dist-all: distdir dist-bzip2 dist-gzip dist-zip
+
+distdir:
+	mkdir -p dist
+
+VERSION=luajson-$(shell git describe --abbrev=4 HEAD 2>/dev/null)
+dist-bzip2: distdir
+	git archive --format=tar --prefix=$(VERSION)/ HEAD | bzip2 -9v > $(DIST_DIR)/$(VERSION).tar.bz2
+dist-gzip: distdir
+	git archive --format=tar --prefix=$(VERSION)/ HEAD | gzip -9v > $(DIST_DIR)/$(VERSION).tar.gz
+dist-zip: distdir
+	git archive --format=zip --prefix=$(VERSION)/ HEAD > $(DIST_DIR)/$(VERSION).zip
+
+# Config to make sure that Lua uses the contained Lua code
+LUA_PATH_SETUP=LUA_PATH="?/init.lua;../lua/?.lua;../lua/?/init.lua;$(LUA_PATH);"
+LUA_SETUP=LUA_OLD_INIT="$(LUA_INIT)" LUA_INIT="@hook_require.lua" $(LUA_PATH_SETUP)
+check-regression:
+	cd tests && $(LUA_SETUP) lua regressionTest.lua
+check-unit:
+	cd tests && $(LUA_SETUP) lunit lunit-*.lua
+check: check-regression check-unit
+
+
+distcheck: dist-bzip2
+	mkdir -p tmp
+	tar -C tmp -xf $(DIST_DIR)/$(VERSION).tar.bz2
+	cd tmp/$(VERSION) && make check
+	rm -rf tmp
diff --git a/luajson-1.2.1/README b/luajson-1.2.1/README
new file mode 100644
index 0000000..16d52ff
--- /dev/null
+++ b/luajson-1.2.1/README
@@ -0,0 +1,59 @@
+LuaJSON
+	JSON Parser/Constructor for Lua
+
+Author:	Thomas Harning Jr. <harningt@gmail.com>
+
+Source code:
+    http://repo.or.cz/luajson
+
+Bug reports:
+    http://github.com/harningt/luajson
+    harningt@gmail.com
+
+Requirements
+	Lua 5.1
+	LPeg (Tested with 0.7, 0.8, 0.9 ... 0.6 mostly works)
+	For regressionTest:
+		lfs (Tested with 1.4.1)
+	For lunit-tests:
+		lunit >= 0.4
+
+License
+	All-but tests: MIT-style, See LICENSE for details
+	tests/*:       Public Domain / MIT - whichever is least restrictive
+
+Module/Function overview:
+	json.encode (callable module referencing json.encode.encode)
+	--encode ( value : ANY-valid )
+
+		Takes in a JSON-encodable value and returns the JSON-encoded text
+		Valid input types:
+			table
+			array-like table (spec below)
+			string
+			number
+			boolean
+			'null' - represented by json.util.null
+		Table keys (string,number,boolean) are encoded as strings, others are erroneus
+		Table values are any valid input-type
+		Array-like tables are converted into JSON arrays...
+			Position 1 maps to JSON Array position 0
+	--isEncodable ( value : ANY )
+		Returns a boolean stating whether is is encodeable or not
+		NOTE: Tables/arrays are not deeply inspected
+
+	json.decode (callable module referencing json.decode.decode)
+	--decode	(data : string, strict : optional boolean)
+		Takes in a string of JSON data and converts it into a Lua object
+		If 'strict' is set, then the strict JSON rule-set is used
+
+	json.util
+	--printValue (tab : ANY, name : string)
+			recursively prints out all object values - if duplicates found, reference printed
+	--null
+			Reference value to represent 'null' in a well-defined way to
+			allow for null values to be inserted into an array/table
+
+Attribution:
+	parsing test suite from JSON_checker project of http://www.json.org/
+	No listed license for these files in their package.
diff --git a/luajson-1.2.1/ReleaseNotes.txt b/luajson-1.2.1/ReleaseNotes.txt
new file mode 120000
index 0000000..e05acb0
--- /dev/null
+++ b/luajson-1.2.1/ReleaseNotes.txt
@@ -0,0 +1 @@
+docs/ReleaseNotes-1.2.1.txt
\ No newline at end of file
diff --git a/luajson-1.2.1/docs/LuaJSON.txt b/luajson-1.2.1/docs/LuaJSON.txt
new file mode 100644
index 0000000..c18e2e4
--- /dev/null
+++ b/luajson-1.2.1/docs/LuaJSON.txt
@@ -0,0 +1,206 @@
+LuaJSON(3)
+==========
+:Author: Thomas Harning
+:Email:  harningt@gmail.com
+:Date:   2009/04/29
+
+NAME
+----
+luajson - JSON encoder/decoder for Lua
+
+SYNOPSIS
+--------
+require("json")
+
+json.decode("json-string" [, parameters])
+
+json.decode.getDecoder(parameters)
+
+json.encode(lua_value [, parameters])
+
+json.encode.getEncoder(parameters)
+
+DESCRIPTION
+-----------
+json.decode("json-string" [, parameters])::
+    Obtains a JSON decoder using `getDecoder` with the parameters specified,
+    then performs the decoding operation.
+
+json.encode(lua_value [, parameters])::
+    Obtains a JSON encoder using `getEncoder` with the parameters specified,
+    then performs the encoding operation.
+
+json.decode.getDecoder(parameters)::
+    Obtains a JSON decoder configured with the given parameters or defaults.
+
+json.encode.getEncoder(parameters)::
+    Obtains a JSON encoder configured with the given parameters or defaults.
+
+json.encode.strict::
+    A default parameter specification containing 'strict' rules for encoding
+
+json.decode.strict::
+    A default parameter specification containing 'strict' rules for decoding
+
+=== COMMON PARAMETERS
+
+initialObject : boolean::
+    Specifies if the outermost element be an array or object
+
+allowUndefined : boolean::
+    Specifies if 'undefined' is an allowed value
+
+null : any::
+    Placeholder object for null values
+
+undefined : any::
+    Placeholder for undefined values
+
+number.nan : boolean::
+    Specifies if NaN is an allowed value
+
+number.inf : boolean::
+    Specifies if +/-Infinity is an allowed value
+
+=== ENCODER-SPECIFIC PARAMETERS
+
+preProcess : `function(object)`::
+    Called for every value to be encoded, optionally altering.
+    If returns `nil` then no value change occurs.
+
+output : function::
+    Function that returns an encoder specification (TBD), if null
+    default used that returns a string.
+
+array.isArray : `function(object)`::
+    If `true`/`false` returned, then the value is authoritatively
+    an array or not
+
+strings.xEncode : boolean::
+    Specifies if binary values are to be encoded with \xNN rather than \uNNNN
+
+strings.encodeSet : string::
+    http://www.lua.org/manual/5.1/manual.html#5.4.1[gmatch-style] set of
+    characters that need to be escaped (to be contained in `[]`)
+
+strings.encodeSetAppend : string::
+    Set of characters that need to be escaped (to be contained in `[]`).
+    Appended to the current encodeSet.
+
+==== Default Configuration
+[source,lua]
+----
+array.isArray == json-util's isArray implementation
+allowUndefined = true
+number.nan = true
+number.inf = true
+strings.xEncode = false
+strings.encodeSet = '\\"/%z\1-\031'
+----
+
+==== Strict Configuration
+[source,lua]
+----
+initialObject = true
+allowUndefined = false
+number.nan = false
+number.inf = false
+----
+
+=== DECODER-SPECIFIC PARAMETERS
+
+unicodeWhitespace : boolean::
+    Specifies if unicode whitespace characters are counted
+
+array.trailingComma / object.trailingComma : boolean::
+    Specifies if extraneous trailing commas are ignored in declaration
+
+calls.defs : map<string | LPEG, function | boolean>::
+    Defines set of specifically permitted function definitions.
+    If boolean value, determines if allowed or not, decoded as a call object.
+    Function return-value is the decoded result.
+    Function definition:  `function(name, [arguments])` : output-value
+
+calls.allowUndefined : boolean::
+    Specifies if undefined call definitions are decoded as call objects.
+
+number.frac : boolean::
+    Specifies if numbers can have a decimal component (ex: `.01`)
+
+number.exp : boolean::
+    Specifies if exponents are allowed (ex: `1e2`)
+
+number.hex : boolean::
+    Specifies if hexadecimal numbers are allowed (ex: `0xDEADBEEF`)
+
+object.number : boolean::
+    Specifies if numbers can be object keys
+
+object.identifier : boolean::
+    Specifies if unquoted 'identifiers' can be object keys (matching `[A-Za-z_][A-Za-z0-9_]*`)
+
+strings.badChars : string::
+    Set of characters that should not be present in a string
+
+strings.additionalEscapes : LPeg expression::
+    LPeg expression to handle output (ex: `lpeg.C(1)` would take `\k` and spit out `k`)
+
+strings.escapeCheck : non-consuming LPeg expression::
+    LPeg expression to check if a given character is allowed to be an escape value
+
+strings.decodeUnicode::
+    `function (XX, YY)` handling \uXXYY situation to output decoded unicode sequence
+
+strings.strict_quotes : boolean::
+    Specifies if the `'` character is considered a quoting specifier
+
+==== Default configuration
+
+[source,lua]
+----
+unicodeWhitespace = true
+initialObject = false
+allowUndefined = true
+array.trailingComma = true
+number.frac = true
+number.exp = true
+number.hex = false
+object.number = true
+object.identifier = true
+object.trailingComma = true
+strings.badChars = '' -- No characters considered bad in a string
+strings.additionalEscapes = false, -- disallow untranslated escapes
+strings.escapeCheck = #lpeg.S('bfnrtv/\\"xu\'z'),
+strings.decodeUnicode = utf8DecodeUnicode,
+strings.strict_quotes = false
+----
+
+==== Strict configuration
+
+[source,lua]
+----
+initialObject = true
+allowUndefined = false
+array.trailingComma = false
+object.identifier = false
+object.trailingComma = false
+strings.badChars = '\b\f\n\r\t\v'
+strings.additionalEscapes = false -- no additional escapes
+strings.escapeCheck = #lpeg.S('bfnrtv/\\"u') --only these are allowed to be escaped
+strings.strict_quotes = true
+----
+
+AUTHOR
+------
+Written by Thomas Harning Jr., <harningt@gmail.com>
+
+REFERENCES
+----------
+http://www.inf.puc-rio.br/~roberto/lpeg[LPeg]
+
+http://json.org[JSON]
+
+COPYING
+-------
+Copyright (C) 2008-2009 Thomas Harning Jr.  Free use of this software is granted
+under the terms of the MIT license.
diff --git a/luajson-1.2.1/docs/ReleaseNotes-0.10.txt b/luajson-1.2.1/docs/ReleaseNotes-0.10.txt
new file mode 100644
index 0000000..ca678c9
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-0.10.txt
@@ -0,0 +1,105 @@
+luajson v0.10 Release Notes
+===========================
+
+User Visible Changes
+--------------------
+This release changes the system quite a bit from previous versions in
+that there is more configurability.  There still is quite a bit of strong
+defaulting to make it accept more data formats and encode such that the
+most strict decoder *should* decode it.
+
+It is now possible to obtain wrapped-up encoders and decoders with options
+"compiled" in.  With decoders this is particularly bound-up (LPEG patterns),
+encoders take advantage of this with less closure-count.
+
+Extended features of newer LPEG versions can also be used as they are
+available, either via function detection or version # parsing.
+
+New decoder features:
+
+ * Single-quoted strings
+ * Function-call decoding
+ * Generic string management
+   * String post-processing option
+   * UTF-16 -> UTF-8 code decoding for "\uXXXX" from Emil Renner Berthing by default (not req)
+ * Handle extended UTF-8 spacing characters and BOF for inter-element spacing
+
+New encoder features:
+
+ * Function-call encoding
+ * String pre-processing option
+ * Fully modular encoding system
+ * Encoding with similar option system as decoding
+
+
+Plans for next release
+----------------------
+
+0.11
+
+ * UTF-8 encoding/decoding validation (currently decoding only supported)
+ * Optional \xXX encoding
+ * JSON encoding with fully 'strict' options
+ * Generic output mechanism (ropes, IO, etc)
+
+1.0 beta
+
+ * Full API documentation
+ * Stable encoder/decoder option-apis.  Final 1.0 release will maintain
+   that all options used in code will be future-proof, at least until 2.0
+
+Updates since 0.9.1
+===================
+
+Emil Renner Berthing (1):
+	decoder:
+		Added proper utf8 decoding of strings
+Thomas Harning Jr (38):
+	-ungrouped-
+		Merge branch '0.9-rockspec'
+	base:
+		Setup 0.9.1 rockspec with md5 of luaforge release
+		added luarocks module to check out luajson from git (requires git patch)
+		Preparing for next release pre-emptively
+	decode-util:
+		during a table merge, if a nil is located, skip it
+	decoder/test:
+		Added preliminary function-call handling
+		Require name is string and func is function
+		Support both patterns and strings as function name specifiers
+		function calls receive as first argument the name used
+		added support for multiple arguments to functions
+		Moved function-call decoder to separate module
+		added string post-processing utility
+	decoder/tests:
+		adds support for single-quoted strings w/ expected escape-handling
+		support unicode whitespaces as whitespace around values
+	decoder:
+		Fully modularized strings/number/calls data-types
+		Refactored boolean/null/undefined out into the 'others' module
+		Provide workaround for missing lpeg.type in lpeg 0.6, 0.7, ...
+		More stabilization of string decoder configuration as well as hooking unicode-handling in
+		optimized 'number' option-defaulting
+		unified configuration system into a fast-cached Tokend which only permits card-readng ops (writing in seprate referece...)
+		Fixed return assertion to prevent 'Invalid JSON data' from being returned as second result
+		Added simple LPEG version parser "x.y.z.." => x.y
+		Added support for LPEG 0.9 accumulator replacement (fold) which may be faster
+		string.char => string_char for optimization in utf8 decoder
+	encoder/decoder:
+		added support for 'undefined' value
+	encoder/test:
+		exposed and test string preprocessing option
+	encoder:
+		add string preprocessor handler (for encoding->utf8 mgmt)
+		Break apart the encoder into distinct modules + add call encoding
+		split out number encoder into own file to mirror decoder
+		added applicable configuration options from the decoder to the number encoder
+		enhanced configuration support to match the decoder's optionset where appropriate
+		added 'initialObject' check to assert that the root object is in fact an object/array
+		mirrored decoder's getDecoder => getEncoder setup
+		performed full modularization of the encoder + added function-encode tests
+	tests:
+		Removed package.path alteration since 'make check' handles that as well as luarocks
+		applied configuration optimizations take advantage of the encoder optimizations and simplifications from the decoders
+		added UTF-16 => UTF-8 encoder test
+		extends UTF tests with boundary tests and test # for break detect
diff --git a/luajson-1.2.1/docs/ReleaseNotes-0.9.1.txt b/luajson-1.2.1/docs/ReleaseNotes-0.9.1.txt
new file mode 100644
index 0000000..a3e4e1c
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-0.9.1.txt
@@ -0,0 +1,19 @@
+luajson v0.9.1 Release Notes
+============================
+
+User Visible Changes
+--------------------
+LuaRocks package created.
+
+Plans for next release
+----------------------
+ * Make the encoder customizable in a manner similar to the decoder
+ * Try to create an integration point for unicode handling
+ * Add in custom 'function' handling for decoder (ex: b64(stringvalue))
+
+Updates since 0.9
+=================
+
+Thomas Harning Jr (1):
+	base:
+		Preparation to make luajson work as a luarocks rock
diff --git a/luajson-1.2.1/docs/ReleaseNotes-0.9.txt b/luajson-1.2.1/docs/ReleaseNotes-0.9.txt
new file mode 100644
index 0000000..82d5930
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-0.9.txt
@@ -0,0 +1,43 @@
+luajson v0.9 Release Notes
+==========================
+
+User Visible Changes
+--------------------
+There are more tests added in using the lunit framework.  These are particularly useful for
+testing and debugging small components in the luajson decoder/encoder sections.
+
+Decoders are now customizable in a modular manner.  For example:  You can construct a decoder
+that allows for NaN and Inf values, but be strict on everything else.  The support framework
+should permit for more enhancements and custom elements.
+
+Plans for next release
+----------------------
+ * Make the encoder customizable in a manner similar to the decoder
+ * Try to create an integration point for unicode handling
+ * Add in custom 'function' handling for decoder (ex: b64(stringvalue))
+ * Create luarocks
+
+Updates since 0.6
+=================
+
+Thomas Harning Jr (15):
+	base:
+		Added changelog (with details for 0.6)
+		Noted lunit 0.4 requirement
+		Make distcheck properly run the check inside the dist
+	decoder/encoder:
+		Added support for primitive Array metatable marker to mark arrays as such
+	decoder/test:
+		Added hex decode capability
+	decoder:
+		Cleaned up unused values in the base decoder
+		Refactored decoding mechanism to permit building even more customized decoders
+		Fixed decoder generation to return cached versions
+		fixed decoder to remove misnamed parameters (causing failed tests)
+		Allow negative inf
+	test:
+		Reconfigured the tests to behave more correctly and allow for a simpler addition mechanism.
+		Enhanced the regression tests to handle roundtripping in a sane manner
+		Updated regression tests for roundtripping to have a better output format and handle outer whitespace and moved tests
+		Added lunit-based tests for fine-grained tests
+		Made lunit tests use 'setup' to simplify decoder hooking
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.0.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.0.1.txt
new file mode 100644
index 0000000..ae679c7
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.0.1.txt
@@ -0,0 +1,39 @@
+luajson v1.0.1 Release Notes
+============================
+
+User Visible Changes
+--------------------
+Duplicate references are allowed if it does not cause circular references.
+
+This allows something like the following to be valid, where it was not before:
+
+    a = {1, 2, 3}
+    json.encode({a, a})
+
+Decoding this will not be handled in any special way, it will be encoded as:
+
+    [ [1,2,3], [1,2,3] ]
+
+Plans for next release
+----------------------
+The 1.1 release will contain support for arbitrary configurations in the same
+manner as the built-in configurations.  It will also contain support for
+a simple decoder where `null` and `undefined` values are mapped to nil,
+rather than the more complicated round-trip capable constants.
+
+Updates since 1.0
+=================
+
+Thomas Harning Jr (3):
+	base:
+		updates utility to help construct lua rocks to provide stable output
+	encoder:
+		adds support for non-circular duplicate object references
+	tests:
+		adds encoding test for circular/non-circular duplicate values
+
+Contributions
+=============
+
+Thanks to Marcus Irven <marcus@marcusirven.com> for reporting
+the issue with duplicate objects that aren't circular.
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.0.2.txt b/luajson-1.2.1/docs/ReleaseNotes-1.0.2.txt
new file mode 100644
index 0000000..a73e20f
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.0.2.txt
@@ -0,0 +1,46 @@
+luajson v1.0.2 Release Notes
+============================
+
+User Visible Changes
+--------------------
+In Windows, Lua's tostring and tonumber handling occur differently for
+the boundary cases of NaN, Infinity, and -Infinity values.  This broke
+Windows encoding/decoding of JSON for which these values are present.
+
+Example input/outputs:
+
+Windows:
+
+ * tonumber("Infinity") == nil
+ * tostring(1/0) == "1.#INF"
+ * tostring(0/0) == "-1.#IND"
+
+Linux:
+
+ * tonumber("Infinity") == inf
+ * tostring(1/0) == "inf"
+ * tostring(0/0) == "nan"
+
+The code that decoded was changed to report the output manually on decode
+rather than decode 'generically' using 'tonumber'.
+
+The code that encoded was changed to use numerical equivalence checking
+before returning what 'tostring' would have, which should catch nearly
+all cases.
+
+Checks were updated to do:
+
+ * nan  =>  value ~= value
+ * inf  =>  value == math.huge
+ * -inf =>  value == -math.huge
+
+Plans for next release
+----------------------
+Bugfixes only in the 1.0.x series.
+
+Updates since 1.0.1
+===================
+
+Thomas Harning Jr (2):
+	decoder/encoder:
+		better handles number encoding/decoding for cases where tonumber/tostring don't work as expected
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.0.txt b/luajson-1.2.1/docs/ReleaseNotes-1.0.txt
new file mode 100644
index 0000000..f69e556
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.0.txt
@@ -0,0 +1,93 @@
+luajson v1.0 Release Notes
+==========================
+
+User Visible Changes
+--------------------
+This release marks the 1.0 release that has been in the works for quite some time.
+One of the major release items is detailed documentation and a reasonably stable/
+clean API.  Some features have been eliminated since they were not effective or
+used.
+
+Features removed:
+ * Lax number handling... before this release, numbers with ugly definition were
+   permitted, such as leading zeroes, multiple negative signs, ...
+ * String post-processing... this feature was unused and appears to serve no
+   useful purpose.  Removing it made unifying encoding/decoding options simpler
+ * Adds global pre-processing to handle arbitrary conversion of values during
+   encoding.
+
+Changes:
+ * String escape codes updated to match what the JSON spec uses for encoding
+
+Additions:
+ * Add optional \x00 character encoding to handle encoding single bytes
+ * Custom output stream functionality to create optimal output mechanisms
+   that can stream JSON output.
+
+Plans for next release
+----------------------
+Currently there is nothing in the works for the next release.  The project
+is very open to outside suggestions and patches for enhanced functionality...
+so please contribute.
+
+Updates since 0.10
+==================
+
+Thomas Harning Jr (46):
+	-ungrouped-
+		Rockspec 0.10
+		moved lua sources into 'lua' to assist luarocks management
+	base:
+		makefiles learn high bzip2 and gzip compression
+		adds new rockspec for github
+		updated github rockspec to reference all of the files
+		Makefile learns split-apart checking
+		rockspec 0.10-2 update -- previous one had improper luaforge link
+	decoder/strings:
+		removed unused 'postProcess' option
+		removed unused 'null' decoder
+		remove catchall escape handler from default
+		applied minor cleanups
+		added error analysis for strings + generic bad-character utility
+	decoder/tests:
+		remove depth limiting support code, implementation, and tests
+		implemented non-defined call captures and updated tests to handle cases
+		removed lax number handling (leading zeroes, multiple negatives, and spaces between - and digits)
+		fixes ambiguous/invalid hex numbers with decimal/scientific format
+	decoder:
+		reorders replacements based on spec, adds 'x' escape
+		allow whitespace before strict object/array
+		generalizes decoding using grammar entries
+	docs:
+		preliminary documentation of options
+		created markdown documentation to be translated into manpage-style documentation
+		moves documentation to asciidoc
+	encoder/decoder/tests:
+		moves json.decode.util.merge => json.util.merge
+		call-generation/handling moved to json.util and unified
+		removes discrimination between calls with 1 and * arguments
+	encoder/decoder:
+		applied license headers to files missing them
+	encoder/tests:
+		move preprocessing to root to permit global pre-processor (ex: take special strings and base64-encode to call)
+	encoder:
+		add vertical tabulation character to the encoded set
+		adds \xXX encoding and customizable encoding set
+		adds custom output-encoder support while keeping default case optimal using templates
+		adds output-stream writer for encoding
+		consulted JSON specification and updated string definitions to match
+		note encoding > 7F with escapes is hazardous
+		properly capture expected range-of-characters to map
+		updates strict encoding to use correct calls check and ordering
+		correct language of disabled 'undefined' value
+		cleans up code and errors
+		removes extraneous 'defs' from the default options
+	tests:
+		adds \u and \x escape encoding/decoding test cases
+		test strict form of string decoding tests
+		updates strict string test to use strict encoder
+		regression-test uses test strict encoder in strict tests
+		adds strict encoder regression tests
+		report error cause during regressionTest encoding failures
+		added pre-value whitespace tests
+		updated tests to match new stricter default syntax
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.1.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.1.1.txt
new file mode 100644
index 0000000..d75fafd
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.1.1.txt
@@ -0,0 +1,51 @@
+
+luajson v1.1.1 Release Notes
+============================
+
+User Visible Changes
+--------------------
+In Windows, Lua's tostring and tonumber handling occur differently for
+the boundary cases of NaN, Infinity, and -Infinity values.  This broke
+Windows encoding/decoding of JSON for which these values are present.
+
+Example input/outputs:
+
+Windows:
+
+ * tonumber("Infinity") == nil
+ * tostring(1/0) == "1.#INF"
+ * tostring(0/0) == "-1.#IND"
+
+Linux:
+
+ * tonumber("Infinity") == inf
+ * tostring(1/0) == "inf"
+ * tostring(0/0) == "nan"
+
+The code that decoded was changed to report the output manually on decode
+rather than decode 'generically' using 'tonumber'.
+
+The code that encoded was changed to use numerical equivalence checking
+before returning what 'tostring' would have, which should catch nearly
+all cases.
+
+Checks were updated to do:
+
+ * nan  =>  value ~= value
+ * inf  =>  value == math.huge
+ * -inf =>  value == -math.huge
+
+Plans for next release
+----------------------
+The next version should hopefully have more error reporting capabilities,
+such as returning where an error occurred and possibly details.
+How this will be done is a research-item.
+
+Updates since 1.1
+=================
+
+Thomas Harning Jr (3):
+	-ungrouped-
+		Merge branch '1.0.x'
+	decoder/encoder:
+		better handles number encoding/decoding for cases where tonumber/tostring don't work as expected
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.1.txt
new file mode 100644
index 0000000..ecf5600
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.1.txt
@@ -0,0 +1,31 @@
+luajson v1.1 Release Notes
+==========================
+
+User Visible Changes
+--------------------
+A new default configuration "simple" is available that does not use
+`json.util.null` and `json.util.undefined` to represent their associated
+JSON values.
+
+There is also a change in the decoding of arrays with nulls to avoid
+special casing it.
+
+Plans for next release
+----------------------
+No plans yet for what a future release might contain.
+
+Updates since 1.0.1
+===================
+
+Thomas Harning Jr (9):
+	-ungrouped-
+		Merge branch '1.0.x'
+	decoder:
+		learns how to handle arbitrary sets of defaults (now + simple)
+		adds support for nil return values
+		fixes bug where function call returns nothing => error
+		adds support for 'simple' decoding to map null and undefined => nil
+		removes special casing of null values in an array
+		adds support for caching new arbitrary configs
+	tests:
+		tests added for simple/default decoders stand-alone, in arrays, in objects
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.2.1.txt b/luajson-1.2.1/docs/ReleaseNotes-1.2.1.txt
new file mode 100644
index 0000000..d6aadf7
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.2.1.txt
@@ -0,0 +1,27 @@
+luajson v1.2.1 Release Notes
+============================
+
+User Visible Changes
+--------------------
+LPeg 0.10 now supported.  The only problem was the mechanism for
+version detection.  I now use object detection which should better
+work for future version updates.
+
+Plans for next release
+----------------------
+No change in the plans for the next release.
+For the next feature release, I plan on better fleshing out the enhanced
+error handling and possibly adding in the more customizable output
+system.  For previews of the features that might make it into the
+next release, please see the "next" branch.  Note that this branch
+is volatile and features may vanish rather than be reverted for cleanliness.
+
+Enhanced error handling introduced in LPeg 0.10 might help this task.
+
+
+Updates since 1.2
+=================
+
+Thomas Harning Jr (6):
+	decode/object:
+		compatibility fix for LPeg 0.10 - function-checking vs number parsing
diff --git a/luajson-1.2.1/docs/ReleaseNotes-1.2.txt b/luajson-1.2.1/docs/ReleaseNotes-1.2.txt
new file mode 100644
index 0000000..22d319f
--- /dev/null
+++ b/luajson-1.2.1/docs/ReleaseNotes-1.2.txt
@@ -0,0 +1,67 @@
+luajson v1.2 Release Notes
+==========================
+
+Tested LPeg versions:
+
+ * 0.9 - pass
+ * 0.8 - pass
+ * 0.7 - pass
+ * 0.6 - fail : cannot handle 'nil' returns -> tranforms into booleans
+
+Note that 0.6 passes strict mode tests and behaviors.  It just breaks
+down when decoding the plain return value `null` or `undefined` that
+would result in a `nil` return value.
+
+User Visible Changes
+--------------------
+
+setObjectKey
+~~~~~~~~~~~~
+Thanks to Alexander Gladysh, we now have the "setObjectKey"
+hook to permit more customizable behavior during object construction.
+
+There is a new 'object' option that you can set to handle custom
+key-value setting.  If you set in the configuration table
+.object.setObjectKey to a function with the signature
+`(tab, key, value)`, you will override the `rawset` style behavior.
+
+Example:
+    json.decode("{'1':true, x:true}")
+	--> { ["1"] = true, x = true }
+	function newSetObjectKey(tab, key, value)
+		local numkey = tonumber(key)
+		key = numkey or key
+		rawset(tab, key, value)
+	end
+	json.decode("{'1':true, x:true}", { object = { setObjectKey = newSetObjectKey } })
+	--> { [1] = true, x = true }
+
+require builtins update
+~~~~~~~~~~~~~~~~~~~~~~~
+Also changed is the major change to `require` as many of the default
+packages as possible to better help custom embedding scenarios where
+'default' tables such as `io` and `os` may require on-demand loading
+via `require`.
+
+Plans for next release
+----------------------
+For the next feature release, I plan on better fleshing out the enhanced
+error handling and possibly adding in the more customizable output
+system.  For previews of the features that might make it into the
+next release, please see the "next" branch.  Note that this branch
+is volatile and features may vanish rather than be reverted for cleanliness.
+
+Updates since 1.1.1
+===================
+
+Thomas Harning Jr (4):
+	all:
+		pulls in all but base/package modules via require (io,os,string,table,math)
+	decoder:
+		implements setObjectKey for LPeg < 0.9
+		Moves 'setObjectKey' from root of `options` to `options.object`
+	docs:
+		adds reference for where bug reporting should go
+Alexander Gladysh (1):
+	decoder:
+		configurable object key filter
diff --git a/luajson-1.2.1/lua/json.lua b/luajson-1.2.1/lua/json.lua
new file mode 100644
index 0000000..296fb0d
--- /dev/null
+++ b/luajson-1.2.1/lua/json.lua
@@ -0,0 +1,12 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local decode = require("json.decode")
+local encode = require("json.encode")
+local util = require("json.util")
+
+module("json")
+_M.decode = decode
+_M.encode = encode
+_M.util = util
diff --git a/luajson-1.2.1/lua/json/decode.lua b/luajson-1.2.1/lua/json/decode.lua
new file mode 100644
index 0000000..3086366
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode.lua
@@ -0,0 +1,132 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+
+local error = error
+
+local object = require("json.decode.object")
+local array = require("json.decode.array")
+
+local merge = require("json.util").merge
+local util = require("json.decode.util")
+
+local setmetatable, getmetatable = setmetatable, getmetatable
+local assert = assert
+local ipairs, pairs = ipairs, pairs
+local string_char = require("string").char
+
+local require = require
+module("json.decode")
+
+local modulesToLoad = {
+	"array",
+	"object",
+	"strings",
+	"number",
+	"calls",
+	"others"
+}
+local loadedModules = {
+}
+
+default = {
+	unicodeWhitespace = true,
+	initialObject = false
+}
+
+local modes_defined = { "default", "strict", "simple" }
+
+simple = {}
+
+strict = {
+	unicodeWhitespace = true,
+	initialObject = true
+}
+
+-- Register generic value type
+util.register_type("VALUE")
+for _,name in ipairs(modulesToLoad) do
+	local mod = require("json.decode." .. name)
+	for _, mode in pairs(modes_defined) do
+		if mod[mode] then
+			_M[mode][name] = mod[mode]
+		end
+	end
+	loadedModules[name] = mod
+	-- Register types
+	if mod.register_types then
+		mod.register_types()
+	end
+end
+
+-- Shift over default into defaultOptions to permit build optimization
+local defaultOptions = default
+default = nil
+
+
+local function buildDecoder(mode)
+	mode = mode and merge({}, defaultOptions, mode) or defaultOptions
+	local ignored = mode.unicodeWhitespace and util.unicode_ignored or util.ascii_ignored
+	-- Store 'ignored' in the global options table
+	mode.ignored = ignored
+
+	local value_id = util.types.VALUE
+	local value_type = lpeg.V(value_id)
+	local object_type = lpeg.V(util.types.OBJECT)
+	local array_type = lpeg.V(util.types.ARRAY)
+	local grammar = {
+		[1] = mode.initialObject and (ignored * (object_type + array_type)) or value_type
+	}
+	for _, name in pairs(modulesToLoad) do
+		local mod = loadedModules[name]
+		mod.load_types(mode[name], mode, grammar)
+	end
+	-- HOOK VALUE TYPE WITH WHITESPACE
+	grammar[value_id] = ignored * grammar[value_id] * ignored
+	grammar = lpeg.P(grammar) * ignored * lpeg.Cp() * -1
+	return function(data)
+		local ret, next_index = lpeg.match(grammar, data)
+		assert(nil ~= next_index, "Invalid JSON data")
+		return ret
+	end
+end
+
+-- Since 'default' is nil, we cannot take map it
+local defaultDecoder = buildDecoder(default)
+local prebuilt_decoders = {}
+for _, mode in pairs(modes_defined) do
+	if _M[mode] ~= nil then
+		prebuilt_decoders[_M[mode]] = buildDecoder(_M[mode])
+	end
+end
+
+--[[
+Options:
+	number => number decode options
+	string => string decode options
+	array  => array decode options
+	object => object decode options
+	initialObject => whether or not to require the initial object to be a table/array
+	allowUndefined => whether or not to allow undefined values
+]]
+function getDecoder(mode)
+	mode = mode == true and strict or mode or default
+	local decoder = mode == nil and defaultDecoder or prebuilt_decoders[mode]
+	if decoder then
+		return decoder
+	end
+	return buildDecoder(mode)
+end
+
+function decode(data, mode)
+	local decoder = getDecoder(mode)
+	return decoder(data)
+end
+
+local mt = getmetatable(_M) or {}
+mt.__call = function(self, ...)
+	return decode(...)
+end
+setmetatable(_M, mt)
diff --git a/luajson-1.2.1/lua/json/decode/array.lua b/luajson-1.2.1/lua/json/decode/array.lua
new file mode 100644
index 0000000..d7e823a
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/array.lua
@@ -0,0 +1,64 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+
+local util = require("json.decode.util")
+local jsonutil = require("json.util")
+
+local table_maxn = require("table").maxn
+
+local unpack = unpack
+
+module("json.decode.array")
+
+-- Utility function to help manage slighly sparse arrays
+local function processArray(array)
+	local max_n = table_maxn(array)
+	-- Only populate 'n' if it is necessary
+	if #array ~= max_n then
+		array.n = max_n
+	end
+	if jsonutil.InitArray then
+		array = jsonutil.InitArray(array) or array
+	end
+	return array
+end
+
+local defaultOptions = {
+	trailingComma = true
+}
+
+default = nil -- Let the buildCapture optimization take place
+strict = {
+	trailingComma = false
+}
+
+local function buildCapture(options, global_options)
+	local ignored = global_options.ignored
+	-- arrayItem == element
+	local arrayItem = lpeg.V(util.types.VALUE)
+	local arrayElements = lpeg.Ct(arrayItem * (ignored * lpeg.P(',') * ignored * arrayItem)^0 + 0) / processArray
+
+	options = options and jsonutil.merge({}, defaultOptions, options) or defaultOptions
+	local capture = lpeg.P("[")
+	capture = capture * ignored
+		* arrayElements * ignored
+	if options.trailingComma then
+		capture = capture * (lpeg.P(",") + 0) * ignored
+	end
+	capture = capture * lpeg.P("]")
+	return capture
+end
+
+function register_types()
+	util.register_type("ARRAY")
+end
+
+function load_types(options, global_options, grammar)
+	local capture = buildCapture(options, global_options)
+	local array_id = util.types.ARRAY
+	grammar[array_id] = capture
+	util.append_grammar_item(grammar, "VALUE", lpeg.V(array_id))
+end
diff --git a/luajson-1.2.1/lua/json/decode/calls.lua b/luajson-1.2.1/lua/json/decode/calls.lua
new file mode 100644
index 0000000..4f9c8a0
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/calls.lua
@@ -0,0 +1,116 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+local tostring = tostring
+local pairs, ipairs = pairs, ipairs
+local next, type = next, type
+local error = error
+
+local util = require("json.decode.util")
+
+local buildCall = require("json.util").buildCall
+
+local getmetatable = getmetatable
+
+module("json.decode.calls")
+
+local defaultOptions = {
+	defs = nil,
+	-- By default, do not allow undefined calls to be de-serialized as call objects
+	allowUndefined = false
+}
+
+-- No real default-option handling needed...
+default = nil
+strict = nil
+
+local isPattern
+if lpeg.type then
+	function isPattern(value)
+		return lpeg.type(value) == 'pattern'
+	end
+else
+	local metaAdd = getmetatable(lpeg.P("")).__add
+	function isPattern(value)
+		return getmetatable(value).__add == metaAdd
+	end
+end
+
+local function buildDefinedCaptures(argumentCapture, defs)
+	local callCapture
+	if not defs then return end
+	for name, func in pairs(defs) do
+		if type(name) ~= 'string' and not isPattern(name) then
+			error("Invalid functionCalls name: " .. tostring(name) .. " not a string or LPEG pattern")
+		end
+		-- Allow boolean or function to match up w/ encoding permissions
+		if type(func) ~= 'boolean' and type(func) ~= 'function' then
+			error("Invalid functionCalls item: " .. name .. " not a function")
+		end
+		local nameCallCapture
+		if type(name) == 'string' then
+			nameCallCapture = lpeg.P(name .. "(") * lpeg.Cc(name)
+		else
+			-- Name matcher expected to produce a capture
+			nameCallCapture = name * "("
+		end
+		-- Call func over nameCallCapture and value to permit function receiving name
+
+		-- Process 'func' if it is not a function
+		if type(func) == 'boolean' then
+			local allowed = func
+			func = function(name, ...)
+				if not allowed then
+					error("Function call on '" .. name .. "' not permitted")
+				end
+				return buildCall(name, ...)
+			end
+		else
+			local inner_func = func
+			func = function(...)
+				return (inner_func(...))
+			end
+		end
+		local newCapture = (nameCallCapture * argumentCapture) / func * ")"
+		if not callCapture then
+			callCapture = newCapture
+		else
+			callCapture = callCapture + newCapture
+		end
+	end
+	return callCapture
+end
+
+local function buildCapture(options)
+	if not options  -- No ops, don't bother to parse
+		or not (options.defs and (nil ~= next(options.defs)) or options.allowUndefined) then
+		return nil
+	end
+	-- Allow zero or more arguments separated by commas
+	local value = lpeg.V(util.types.VALUE)
+	local argumentCapture = (value * (lpeg.P(",") *  value)^0) + 0
+	local callCapture = buildDefinedCaptures(argumentCapture, options.defs)
+	if options.allowUndefined then
+		local function func(name, ...)
+			return buildCall(name, ...)
+		end
+		-- Identifier-type-match
+		local nameCallCapture = lpeg.C(util.identifier) * "("
+		local newCapture = (nameCallCapture * argumentCapture) / func * ")"
+		if not callCapture then
+			callCapture = newCapture
+		else
+			callCapture = callCapture + newCapture
+		end
+	end
+	return callCapture
+end
+
+function load_types(options, global_options, grammar)
+	local capture = buildCapture(options, global_options)
+	if capture then
+		util.append_grammar_item(grammar, "VALUE", capture)
+	end
+end
diff --git a/luajson-1.2.1/lua/json/decode/number.lua b/luajson-1.2.1/lua/json/decode/number.lua
new file mode 100644
index 0000000..efc7fd6
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/number.lua
@@ -0,0 +1,85 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+local tonumber = tonumber
+local merge = require("json.util").merge
+local util = require("json.decode.util")
+
+module("json.decode.number")
+
+local digit  = lpeg.R("09")
+local digits = digit^1
+
+int = (lpeg.P('-') + 0) * (lpeg.R("19") * digits + digit)
+local int = int
+
+local frac = lpeg.P('.') * digits
+
+local exp = lpeg.S("Ee") * (lpeg.S("-+") + 0) * digits
+
+local nan = lpeg.S("Nn") * lpeg.S("Aa") * lpeg.S("Nn")
+local inf = lpeg.S("Ii") * lpeg.P("nfinity")
+local ninf = lpeg.P('-') * lpeg.S("Ii") * lpeg.P("nfinity")
+local hex = (lpeg.P("0x") + lpeg.P("0X")) * lpeg.R("09","AF","af")^1
+
+local defaultOptions = {
+	nan = true,
+	inf = true,
+	frac = true,
+	exp = true,
+	hex = false
+}
+
+default = nil -- Let the buildCapture optimization take place
+strict = {
+	nan = false,
+	inf = false
+}
+
+local nan_value = 0/0
+local inf_value = 1/0
+local ninf_value = -1/0
+
+--[[
+	Options: configuration options for number rules
+		nan: match NaN
+		inf: match Infinity
+	   frac: match fraction portion (.0)
+	    exp: match exponent portion  (e1)
+	DEFAULT: nan, inf, frac, exp
+]]
+local function buildCapture(options)
+	options = options and merge({}, defaultOptions, options) or defaultOptions
+	local ret = int
+	if options.frac then
+		ret = ret * (frac + 0)
+	end
+	if options.exp then
+		ret = ret * (exp + 0)
+	end
+	if options.hex then
+		ret = hex + ret
+	end
+	-- Capture number now
+	ret = ret / tonumber
+	if options.nan then
+		ret = ret + nan / function() return nan_value end
+	end
+	if options.inf then
+		ret = ret + ninf / function() return ninf_value end + inf / function() return inf_value end
+	end
+	return ret
+end
+
+function register_types()
+	util.register_type("INTEGER")
+end
+
+function load_types(options, global_options, grammar)
+	local integer_id = util.types.INTEGER
+	local capture = buildCapture(options)
+	util.append_grammar_item(grammar, "VALUE", capture)
+	grammar[integer_id] = int / tonumber
+end
diff --git a/luajson-1.2.1/lua/json/decode/object.lua b/luajson-1.2.1/lua/json/decode/object.lua
new file mode 100644
index 0000000..94b699d
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/object.lua
@@ -0,0 +1,103 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+
+local util = require("json.decode.util")
+local merge = require("json.util").merge
+
+local tonumber = tonumber
+local unpack = unpack
+local print = print
+local tostring = tostring
+
+local rawset = rawset
+
+module("json.decode.object")
+
+-- BEGIN LPEG < 0.9 SUPPORT
+local initObject, applyObjectKey
+if not (lpeg.Cg and lpeg.Cf and lpeg.Ct) then
+	function initObject()
+		return {}
+	end
+	function applyObjectKey(tab, key, val)
+		tab[key] = val
+		return tab
+	end
+end
+-- END LPEG < 0.9 SUPPORT
+
+local defaultOptions = {
+	number = true,
+	identifier = true,
+	trailingComma = true
+}
+
+default = nil -- Let the buildCapture optimization take place
+
+strict = {
+	number = false,
+	identifier = false,
+	trailingComma = false
+}
+
+local function buildItemSequence(objectItem, ignored)
+	return (objectItem * (ignored * lpeg.P(",") * ignored * objectItem)^0) + 0
+end
+
+local function buildCapture(options, global_options)
+	local ignored = global_options.ignored
+	local string_type = lpeg.V(util.types.STRING)
+	local integer_type = lpeg.V(util.types.INTEGER)
+	local value_type = lpeg.V(util.types.VALUE)
+	options = options and merge({}, defaultOptions, options) or defaultOptions
+	local key = string_type
+	if options.identifier then
+		key = key + lpeg.C(util.identifier)
+	end
+	if options.number then
+		key = key + integer_type
+	end
+	local objectItems
+	local objectItem = (key * ignored * lpeg.P(":") * ignored * value_type)
+	-- BEGIN LPEG < 0.9 SUPPORT
+	if not (lpeg.Cg and lpeg.Cf and lpeg.Ct) then
+		local set_key = applyObjectKey
+		if options.setObjectKey then
+			local setObjectKey = options.setObjectKey
+			set_key = function(tab, key, val)
+				setObjectKey(tab, key, val)
+				return tab
+			end
+		end
+
+		objectItems = buildItemSequence(objectItem / set_key, ignored)
+		objectItems = lpeg.Ca(lpeg.Cc(false) / initObject * objectItems)
+	-- END LPEG < 0.9 SUPPORT
+	else
+		objectItems = buildItemSequence(lpeg.Cg(objectItem), ignored)
+		objectItems = lpeg.Cf(lpeg.Ct(0) * objectItems, options.setObjectKey or rawset)
+	end
+
+
+	local capture = lpeg.P("{") * ignored
+	capture = capture * objectItems * ignored
+	if options.trailingComma then
+		capture = capture * (lpeg.P(",") + 0) * ignored
+	end
+	capture = capture * lpeg.P("}")
+	return capture
+end
+
+function register_types()
+	util.register_type("OBJECT")
+end
+
+function load_types(options, global_options, grammar)
+	local capture = buildCapture(options, global_options)
+	local object_id = util.types.OBJECT
+	grammar[object_id] = capture
+	util.append_grammar_item(grammar, "VALUE", lpeg.V(object_id))
+end
diff --git a/luajson-1.2.1/lua/json/decode/others.lua b/luajson-1.2.1/lua/json/decode/others.lua
new file mode 100644
index 0000000..01d60db
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/others.lua
@@ -0,0 +1,54 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+local jsonutil = require("json.util")
+local util = require("json.decode.util")
+
+local rawset = rawset
+
+-- Container module for other JavaScript types (bool, null, undefined)
+module("json.decode.others")
+
+-- For null and undefined, use the util.null value to preserve null-ness
+local booleanCapture =
+	lpeg.P("true") * lpeg.Cc(true)
+	+ lpeg.P("false") * lpeg.Cc(false)
+
+local nullCapture = lpeg.P("null")
+local undefinedCapture = lpeg.P("undefined")
+
+local defaultOptions = {
+	allowUndefined = true,
+	null = jsonutil.null,
+	undefined = jsonutil.undefined,
+	setObjectKey = rawset
+}
+
+default = nil -- Let the buildCapture optimization take place
+simple = {
+	null = false,     -- Mapped to nil
+	undefined = false -- Mapped to nil
+}
+strict = {
+	allowUndefined = false
+}
+
+local function buildCapture(options)
+	-- The 'or nil' clause allows false to map to a nil value since 'nil' cannot be merged
+	options = options and jsonutil.merge({}, defaultOptions, options) or defaultOptions
+	local valueCapture = (
+		booleanCapture
+		+ nullCapture * lpeg.Cc(options.null or nil)
+	)
+	if options.allowUndefined then
+		valueCapture = valueCapture + undefinedCapture * lpeg.Cc(options.undefined or nil)
+	end
+	return valueCapture
+end
+
+function load_types(options, global_options, grammar)
+	local capture = buildCapture(options)
+	util.append_grammar_item(grammar, "VALUE", capture)
+end
diff --git a/luajson-1.2.1/lua/json/decode/strings.lua b/luajson-1.2.1/lua/json/decode/strings.lua
new file mode 100644
index 0000000..f092558
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/strings.lua
@@ -0,0 +1,130 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+local util = require("json.decode.util")
+local merge = require("json.util").merge
+
+local tonumber = tonumber
+local string_char = require("string").char
+local floor = require("math").floor
+local table_concat = require("table").concat
+
+local error = error
+module("json.decode.strings")
+local function get_error(item)
+	local fmt_string = item .. " in string [%q] @ %i:%i"
+	return function(data, index)
+		local line, line_index, bad_char, last_line = util.get_invalid_character_info(data, index)
+		local err = fmt_string:format(bad_char, line, line_index)
+		error(err)
+	end
+end
+
+local bad_unicode   = get_error("Illegal unicode escape")
+local bad_hex       = get_error("Illegal hex escape")
+local bad_character = get_error("Illegal character")
+local bad_escape    = get_error("Illegal escape")
+
+local knownReplacements = {
+	["'"] = "'",
+	['"'] = '"',
+	['\\'] = '\\',
+	['/'] = '/',
+	b = '\b',
+	f = '\f',
+	n = '\n',
+	r = '\r',
+	t = '\t',
+	v = '\v',
+	z = '\z'
+}
+
+-- according to the table at http://da.wikipedia.org/wiki/UTF-8
+local function utf8DecodeUnicode(code1, code2)
+	code1, code2 = tonumber(code1, 16), tonumber(code2, 16)
+	if code1 == 0 and code2 < 0x80 then
+		return string_char(code2)
+	end
+	if code1 < 0x08 then
+		return string_char(
+			0xC0 + code1 * 4 + floor(code2 / 64),
+			0x80 + code2 % 64)
+	end
+	return string_char(
+		0xE0 + floor(code1 / 16),
+		0x80 + (code1 % 16) * 4 + floor(code2 / 64),
+		0x80 + code2 % 64)
+end
+
+local function decodeX(code)
+	code = tonumber(code, 16)
+	return string_char(code)
+end
+
+local doSimpleSub = lpeg.C(lpeg.S("'\"\\/bfnrtvz")) / knownReplacements
+local doUniSub = lpeg.P('u') * (lpeg.C(util.hexpair) * lpeg.C(util.hexpair) + lpeg.P(bad_unicode))
+local doXSub = lpeg.P('x') * (lpeg.C(util.hexpair) + lpeg.P(bad_hex))
+
+local defaultOptions = {
+	badChars = '',
+	additionalEscapes = false, -- disallow untranslated escapes
+	escapeCheck = #lpeg.S('bfnrtv/\\"xu\'z'), -- no check on valid characters
+	decodeUnicode = utf8DecodeUnicode,
+	strict_quotes = false
+}
+
+default = nil -- Let the buildCapture optimization take place
+
+strict = {
+	badChars = '\b\f\n\r\t\v',
+	additionalEscapes = false, -- no additional escapes
+	escapeCheck = #lpeg.S('bfnrtv/\\"u'), --only these chars are allowed to be escaped
+	strict_quotes = true
+}
+
+local function buildCaptureString(quote, badChars, escapeMatch)
+	local captureChar = (1 - lpeg.S("\\" .. badChars .. quote)) + (lpeg.P("\\") / "" * escapeMatch)
+	captureChar = captureChar + (-#lpeg.P(quote) * lpeg.P(bad_character))
+	local captureString = captureChar^0
+	return lpeg.P(quote) * lpeg.Cs(captureString) * lpeg.P(quote)
+end
+
+local function buildCapture(options)
+	options = options and merge({}, defaultOptions, options) or defaultOptions
+	local quotes = { '"' }
+	if not options.strict_quotes then
+		quotes[#quotes + 1] = "'"
+	end
+	local escapeMatch = doSimpleSub
+	escapeMatch = escapeMatch + doXSub / decodeX
+	escapeMatch = escapeMatch + doUniSub / options.decodeUnicode
+	if options.additionalEscapes then
+		escapeMatch = escapeMatch + options.additionalEscapes
+	end
+	if options.escapeCheck then
+		escapeMatch = options.escapeCheck * escapeMatch + lpeg.P(bad_escape)
+	end
+	local captureString
+	for i = 1, #quotes do
+		local cap = buildCaptureString(quotes[i], options.badChars, escapeMatch)
+		if captureString == nil then
+			captureString = cap
+		else
+			captureString = captureString + cap
+		end
+	end
+	return captureString
+end
+
+function register_types()
+	util.register_type("STRING")
+end
+
+function load_types(options, global_options, grammar)
+	local capture = buildCapture(options)
+	local string_id = util.types.STRING
+	grammar[string_id] = capture
+	util.append_grammar_item(grammar, "VALUE", lpeg.V(string_id))
+end
diff --git a/luajson-1.2.1/lua/json/decode/util.lua b/luajson-1.2.1/lua/json/decode/util.lua
new file mode 100644
index 0000000..f34335c
--- /dev/null
+++ b/luajson-1.2.1/lua/json/decode/util.lua
@@ -0,0 +1,98 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local lpeg = require("lpeg")
+local select = select
+local pairs, ipairs = pairs, ipairs
+local tonumber = tonumber
+local string_char = require("string").char
+local rawset = rawset
+
+local error = error
+local setmetatable = setmetatable
+
+module("json.decode.util")
+
+-- 09, 0A, 0B, 0C, 0D, 20
+ascii_space = lpeg.S("\t\n\v\f\r ")
+do
+	local chr = string_char
+	local u_space = ascii_space
+	-- \u0085 \u00A0
+	u_space = u_space + lpeg.P(chr(0xC2)) * lpeg.S(chr(0x85) .. chr(0xA0))
+	-- \u1680 \u180E
+	u_space = u_space + lpeg.P(chr(0xE1)) * (lpeg.P(chr(0x9A, 0x80)) + chr(0xA0, 0x8E))
+	-- \u2000 - \u200A, also 200B
+	local spacing_end = ""
+	for i = 0x80,0x8b do
+		spacing_end = spacing_end .. chr(i)
+	end
+	-- \u2028 \u2029 \u202F
+	spacing_end = spacing_end .. chr(0xA8) .. chr(0xA9) .. chr(0xAF)
+	u_space = u_space + lpeg.P(chr(0xE2, 0x80)) * lpeg.S(spacing_end)
+	-- \u205F
+	u_space = u_space + lpeg.P(chr(0xE2, 0x81, 0x9F))
+	-- \u3000
+	u_space = u_space + lpeg.P(chr(0xE3, 0x80, 0x80))
+	-- BOM \uFEFF
+	u_space = u_space + lpeg.P(chr(0xEF, 0xBB, 0xBF))
+	_M.unicode_space = u_space
+end
+
+identifier = lpeg.R("AZ","az","__") * lpeg.R("AZ","az", "__", "09") ^0
+
+hex = lpeg.R("09","AF","af")
+hexpair = hex * hex
+
+comments = {
+	cpp = lpeg.P("//") * (1 - lpeg.P("\n"))^0 * lpeg.P("\n"),
+	c = lpeg.P("/*") * (1 - lpeg.P("*/"))^0 * lpeg.P("*/")
+}
+
+comment = comments.cpp + comments.c
+
+ascii_ignored = (ascii_space + comment)^0
+
+unicode_ignored = (unicode_space + comment)^0
+
+local types = setmetatable({false}, {
+	__index = function(self, k)
+		error("Unknown type: " .. k)
+	end
+})
+
+function register_type(name)
+	types[#types + 1] = name
+	types[name] = #types
+	return #types
+end
+
+_M.types = types
+
+function append_grammar_item(grammar, name, capture)
+	local id = types[name]
+	local original = grammar[id]
+	if original then
+		grammar[id] = original + capture
+	else
+		grammar[id] = capture
+	end
+end
+
+-- Parse the lpeg version skipping patch-values
+-- LPEG <= 0.7 have no version value... so 0.7 is value
+DecimalLpegVersion = lpeg.version and tonumber(lpeg.version():match("^(%d+%.%d+)")) or 0.7
+
+function get_invalid_character_info(input, index)
+	local parsed = input:sub(1, index)
+	local bad_character = input:sub(index, index)
+	local _, line_number = parsed:gsub('\n',{})
+	local last_line = parsed:match("\n([^\n]+.)$") or parsed
+	return line_number, #last_line, bad_character, last_line
+end
+
+function setObjectKeyForceNumber(t, key, value)
+	key = tonumber(key) or key
+	return rawset(t, key, value)
+end
diff --git a/luajson-1.2.1/lua/json/encode.lua b/luajson-1.2.1/lua/json/encode.lua
new file mode 100644
index 0000000..961872d
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode.lua
@@ -0,0 +1,159 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local type = type
+local assert, error = assert, error
+local getmetatable, setmetatable = getmetatable, setmetatable
+local util = require("json.util")
+
+local ipairs, pairs = ipairs, pairs
+local require = require
+
+local output = require("json.encode.output")
+
+local util = require("json.util")
+local util_merge, isCall = util.merge, util.isCall
+
+module("json.encode")
+
+--[[
+	List of encoding modules to load.
+	Loaded in sequence such that earlier encoders get priority when
+	duplicate type-handlers exist.
+]]
+local modulesToLoad = {
+	"strings",
+	"number",
+	"calls",
+	"others",
+	"array",
+	"object"
+}
+-- Modules that have been loaded
+local loadedModules = {}
+
+-- Default configuration options to apply
+local defaultOptions = {}
+-- Configuration bases for client apps
+default = nil
+strict = {
+	initialObject = true -- Require an object at the root
+}
+
+-- For each module, load it and its defaults
+for _,name in ipairs(modulesToLoad) do
+	local mod = require("json.encode." .. name)
+	defaultOptions[name] = mod.default
+	strict[name] = mod.strict
+	loadedModules[name] = mod
+end
+
+-- Merges values, assumes all tables are arrays, inner values flattened, optionally constructing output
+local function flattenOutput(out, values)
+	out = not out and {} or type(out) == 'table' and out or {out}
+	if type(values) == 'table' then
+		for _, v in ipairs(values) do
+			out[#out + 1] = v
+		end
+	else
+		out[#out + 1] = values
+	end
+	return out
+end
+
+-- Prepares the encoding map from the already provided modules and new config
+local function prepareEncodeMap(options)
+	local map = {}
+	for _, name in ipairs(modulesToLoad) do
+		local encodermap = loadedModules[name].getEncoder(options[name])
+		for valueType, encoderSet in pairs(encodermap) do
+			map[valueType] = flattenOutput(map[valueType], encoderSet)
+		end
+	end
+	return map
+end
+
+--[[
+	Encode a value with a given encoding map and state
+]]
+local function encodeWithMap(value, map, state)
+	local t = type(value)
+	local encoderList = assert(map[t], "Failed to encode value, unhandled type: " .. t)
+	for _, encoder in ipairs(encoderList) do
+		local ret = encoder(value, state)
+		if false ~= ret then
+			return ret
+		end
+	end
+	error("Failed to encode value, encoders for " .. t .. " deny encoding")
+end
+
+
+local function getBaseEncoder(options)
+	local encoderMap = prepareEncodeMap(options)
+	if options.preProcess then
+		local preProcess = options.preProcess
+		return function(value, state)
+			local ret = preProcess(value)
+			if nil ~= ret then
+				value = ret
+			end
+			return encodeWithMap(value, encoderMap, state)
+		end
+	end
+	return function(value, state)
+		return encodeWithMap(value, encoderMap, state)
+	end
+end
+--[[
+	Retreive an initial encoder instance based on provided options
+	the initial encoder is responsible for initializing state
+		State has at least these values configured: encode, check_unique, already_encoded
+]]
+function getEncoder(options)
+	options = options and util_merge({}, defaultOptions, options) or defaultOptions
+	local encode = getBaseEncoder(options)
+
+	local function initialEncode(value)
+		if options.initialObject then
+			local errorMessage = "Invalid arguments: expects a JSON Object or Array at the root"
+			assert(type(value) == 'table' and not isCall(value, options), errorMessage)
+		end
+
+		local alreadyEncoded = {}
+		local function check_unique(value)
+			assert(not alreadyEncoded[value], "Recursive encoding of value")
+			alreadyEncoded[value] = true
+		end
+
+		local outputEncoder = options.output and options.output() or output.getDefault()
+		local state = {
+			encode = encode,
+			check_unique = check_unique,
+			already_encoded = alreadyEncoded, -- To unmark encoding when moving up stack
+			outputEncoder = outputEncoder
+		}
+		local ret = encode(value, state)
+		if nil ~= ret then
+			return outputEncoder.simple and outputEncoder.simple(ret) or ret
+		end
+	end
+	return initialEncode
+end
+
+-- CONSTRUCT STATE WITH FOLLOWING (at least)
+--[[
+	encoder
+	check_unique -- used by inner encoders to make sure value is unique
+	already_encoded -- used to unmark a value as unique
+]]
+function encode(data, options)
+	return getEncoder(options)(data)
+end
+
+local mt = getmetatable(_M) or {}
+mt.__call = function(self, ...)
+	return encode(...)
+end
+setmetatable(_M, mt)
diff --git a/luajson-1.2.1/lua/json/encode/array.lua b/luajson-1.2.1/lua/json/encode/array.lua
new file mode 100644
index 0000000..45e300c
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/array.lua
@@ -0,0 +1,99 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local jsonutil = require("json.util")
+
+local type = type
+local pairs = pairs
+local assert = assert
+
+local table = require("table")
+local math = require("math")
+local table_concat = table.concat
+local math_floor, math_modf = math.floor, math.modf
+
+local util_merge = require("json.util").merge
+local util_IsArray = require("json.util").IsArray
+
+module("json.encode.array")
+
+local defaultOptions = {
+	isArray = util_IsArray
+}
+
+default = nil
+strict = nil
+
+--[[
+	Utility function to determine whether a table is an array or not.
+	Criteria for it being an array:
+		* ExternalIsArray returns true (or false directly reports not-array)
+		* If the table has an 'n' value that is an integer >= 1 then it
+		  is an array... may result in false positives (should check some values
+		  before it)
+		* It is a contiguous list of values with zero string-based keys
+]]
+function isArray(val, options)
+	local externalIsArray = options and options.isArray
+
+	if externalIsArray then
+		local ret = externalIsArray(val)
+		if ret == true or ret == false then
+			return ret
+		end
+	end
+	-- Use the 'n' element if it's a number
+	if type(val.n) == 'number' and math_floor(val.n) == val.n and val.n >= 1 then
+		return true
+	end
+	local len = #val
+	for k,v in pairs(val) do
+		if type(k) ~= 'number' then
+			return false
+		end
+		local _, decim = math_modf(k)
+		if not (decim == 0 and 1<=k) then
+			return false
+		end
+		if k > len then -- Use Lua's length as absolute determiner
+			return false
+		end
+	end
+
+	return true
+end
+
+--[[
+	Cleanup function to unmark a value as in the encoding process and return
+	trailing results
+]]
+local function unmarkAfterEncode(tab, state, ...)
+	state.already_encoded[tab] = nil
+	return ...
+end
+function getEncoder(options)
+	options = options and util_merge({}, defaultOptions, options) or defaultOptions
+	local function encodeArray(tab,  state)
+		if not isArray(tab, options) then
+			return false
+		end
+		-- Make sure this value hasn't been encoded yet
+		state.check_unique(tab)
+		local encode = state.encode
+		local compositeEncoder = state.outputEncoder.composite
+		local valueEncoder = [[
+		for i = 1, (composite.n or #composite) do
+			local val = composite[i]
+			PUTINNER(i ~= 1)
+			val = encode(val, state)
+			val = val or ''
+			if val then
+				PUTVALUE(val)
+			end
+		end
+		]]
+		return unmarkAfterEncode(tab, state, compositeEncoder(valueEncoder, '[', ']', ',', tab, encode, state))
+	end
+	return { table = encodeArray }
+end
diff --git a/luajson-1.2.1/lua/json/encode/calls.lua b/luajson-1.2.1/lua/json/encode/calls.lua
new file mode 100644
index 0000000..c1cc646
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/calls.lua
@@ -0,0 +1,61 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local jsonutil = require("json.util")
+
+local table = require("table")
+local table_concat = table.concat
+
+local select = select
+local getmetatable, setmetatable = getmetatable, setmetatable
+local assert = assert
+
+local util = require("json.util")
+
+local util_merge, isCall, decodeCall = util.merge, util.isCall, util.decodeCall
+
+module("json.encode.calls")
+
+
+local defaultOptions = {
+}
+
+-- No real default-option handling needed...
+default = nil
+strict = nil
+
+
+--[[
+	Encodes 'value' as a function call
+	Must have parameters in the 'callData' field of the metatable
+		name == name of the function call
+		parameters == array of parameters to encode
+]]
+function getEncoder(options)
+	options = options and util_merge({}, defaultOptions, options) or defaultOptions
+	local function encodeCall(value, state)
+		if not isCall(value) then
+			return false
+		end
+		local encode = state.encode
+		local name, params = decodeCall(value)
+		local compositeEncoder = state.outputEncoder.composite
+		local valueEncoder = [[
+		for i = 1, (composite.n or #composite) do
+			local val = composite[i]
+			PUTINNER(i ~= 1)
+			val = encode(val, state)
+			val = val or ''
+			if val then
+				PUTVALUE(val)
+			end
+		end
+		]]
+		return compositeEncoder(valueEncoder, name .. '(', ')', ',', params, encode, state)
+	end
+	return {
+		table = encodeCall,
+		['function'] = encodeCall
+	}
+end
diff --git a/luajson-1.2.1/lua/json/encode/number.lua b/luajson-1.2.1/lua/json/encode/number.lua
new file mode 100644
index 0000000..62d5765
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/number.lua
@@ -0,0 +1,46 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local tostring = tostring
+local assert = assert
+local util = require("json.util")
+local huge = require("math").huge
+
+module("json.encode.number")
+
+local defaultOptions = {
+	nan = true,
+	inf = true
+}
+
+default = nil -- Let the buildCapture optimization take place
+strict = {
+	nan = false,
+	inf = false
+}
+
+local function encodeNumber(number, options)
+	if number ~= number then
+		assert(options.nan, "Invalid number: NaN not enabled")
+		return "NaN"
+	end
+	if number == huge then
+		assert(options.inf, "Invalid number: Infinity not enabled")
+		return "Infinity"
+	end
+	if number == -huge then
+		assert(options.inf, "Invalid number: Infinity not enabled")
+		return "-Infinity"
+	end
+	return tostring(number)
+end
+
+function getEncoder(options)
+	options = options and util.merge({}, defaultOptions, options) or defaultOptions
+	return {
+		number = function(number, state)
+			return encodeNumber(number, options)
+		end
+	}
+end
diff --git a/luajson-1.2.1/lua/json/encode/object.lua b/luajson-1.2.1/lua/json/encode/object.lua
new file mode 100644
index 0000000..262742d
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/object.lua
@@ -0,0 +1,67 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local pairs = pairs
+local assert = assert
+
+local type = type
+local tostring = tostring
+
+local table_concat = require("table").concat
+local util_merge = require("json.util").merge
+
+module("json.encode.object")
+
+local defaultOptions = {
+}
+
+default = nil
+strict = nil
+
+--[[
+	Cleanup function to unmark a value as in the encoding process and return
+	trailing results
+]]
+local function unmarkAfterEncode(tab, state, ...)
+	state.already_encoded[tab] = nil
+	return ...
+end
+--[[
+	Encode a table as a JSON Object ( keys = strings, values = anything else )
+]]
+local function encodeTable(tab, options, state)
+	-- Make sure this value hasn't been encoded yet
+	state.check_unique(tab)
+	local encode = state.encode
+	local compositeEncoder = state.outputEncoder.composite
+	local valueEncoder = [[
+	local first = true
+	for k, v in pairs(composite) do
+		local ti = type(k)
+		assert(ti == 'string' or ti == 'number' or ti == 'boolean', "Invalid object index type: " .. ti)
+		local name = encode(tostring(k), state)
+		if first then
+			first = false
+		else
+			name = ',' .. name
+		end
+		PUTVALUE(name .. ':')
+		local val = encode(v, state)
+		val = val or ''
+		if val then
+			PUTVALUE(val)
+		end
+	end
+	]]
+	return unmarkAfterEncode(tab, state, compositeEncoder(valueEncoder, '{', '}', nil, tab, encode, state))
+end
+
+function getEncoder(options)
+	options = options and util_merge({}, defaultOptions, options) or defaultOptions
+	return {
+		table = function(tab, state)
+			return encodeTable(tab, options, state)
+		end
+	}
+end
diff --git a/luajson-1.2.1/lua/json/encode/others.lua b/luajson-1.2.1/lua/json/encode/others.lua
new file mode 100644
index 0000000..ea2c88f
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/others.lua
@@ -0,0 +1,55 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local tostring = tostring
+
+local assert = assert
+local jsonutil = require("json.util")
+local util_merge = require("json.util").merge
+local type = type
+
+module("json.encode.others")
+
+-- Shortcut that works
+encodeBoolean = tostring
+
+local defaultOptions = {
+	allowUndefined = true,
+	null = jsonutil.null,
+	undefined = jsonutil.undefined
+}
+
+default = nil -- Let the buildCapture optimization take place
+strict = {
+	allowUndefined = false
+}
+
+function getEncoder(options)
+	options = options and util_merge({}, defaultOptions, options) or defaultOptions
+	local function encodeOthers(value, state)
+		if value == options.null then
+			return 'null'
+		elseif value == options.undefined then
+			assert(options.allowUndefined, "Invalid value: Unsupported 'Undefined' parameter")
+			return 'undefined'
+		else
+			return false
+		end
+	end
+	local function encodeBoolean(value, state)
+		return value and 'true' or 'false'
+	end
+	local nullType = type(options.null)
+	local undefinedType = options.undefined and type(options.undefined)
+	-- Make sure that all of the types handled here are handled
+	local ret = {
+		boolean = encodeBoolean,
+		['nil'] = function() return 'null' end,
+		[nullType] = encodeOthers
+	}
+	if undefinedType then
+		ret[undefinedType] = encodeOthers
+	end
+	return ret
+end
diff --git a/luajson-1.2.1/lua/json/encode/output.lua b/luajson-1.2.1/lua/json/encode/output.lua
new file mode 100644
index 0000000..a5dbd79
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/output.lua
@@ -0,0 +1,84 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local type = type
+local assert, error = assert, error
+local table_concat = require("table").concat
+local loadstring = loadstring
+
+local io = require("io")
+
+local setmetatable = setmetatable
+
+local output_utility = require("json.encode.output_utility")
+
+module("json.encode.output")
+
+local tableCompositeCache = setmetatable({}, {__mode = 'v'})
+
+local TABLE_VALUE_WRITER = [[
+	ret[#ret + 1] = %VALUE%
+]]
+
+local TABLE_INNER_WRITER = ""
+
+--[[
+	nextValues can output a max of two values to throw into the data stream
+	expected to be called until nil is first return value
+	value separator should either be attached to v1 or in innerValue
+]]
+local function defaultTableCompositeWriter(nextValues, beginValue, closeValue, innerValue, composite, encode, state)
+	if type(nextValues) == 'string' then
+		local fun = output_utility.prepareEncoder(defaultTableCompositeWriter, nextValues, innerValue, TABLE_VALUE_WRITER, TABLE_INNER_WRITER)
+		local ret = {}
+		fun(composite, ret, encode, state)
+		return beginValue .. table_concat(ret, innerValue) .. closeValue
+	end
+end
+
+-- no 'simple' as default action is just to return the value
+function getDefault()
+	return { composite = defaultTableCompositeWriter }
+end
+
+-- BEGIN IO-WRITER OUTPUT
+local IO_INNER_WRITER = [[
+	if %WRITE_INNER% then
+		state.__outputFile:write(%INNER_VALUE%)
+	end
+]]
+local IO_VALUE_WRITER = [[
+	state.__outputFile:write(%VALUE%)
+]]
+
+local function buildIoWriter(output)
+	if not output then -- Default to stdout
+		output = io.output()
+	end
+	local function ioWriter(nextValues, beginValue, closeValue, innerValue, composite, encode, state)
+		-- HOOK OUTPUT STATE
+		state.__outputFile = output
+		if type(nextValues) == 'string' then
+			local fun = output_utility.prepareEncoder(ioWriter, nextValues, innerValue, IO_VALUE_WRITER, IO_INNER_WRITER)
+			local ret = {}
+			output:write(beginValue)
+			fun(composite, ret, encode, state)
+			output:write(closeValue)
+			return nil
+		end
+	end
+
+	local function ioSimpleWriter(encoded)
+		if encoded then
+			output:write(encoded)
+		end
+		return nil
+	end
+	return { composite = ioWriter, simple = ioSimpleWriter }
+end
+function getIoWriter(output)
+	return function()
+		return buildIoWriter(output)
+	end
+end
diff --git a/luajson-1.2.1/lua/json/encode/output_utility.lua b/luajson-1.2.1/lua/json/encode/output_utility.lua
new file mode 100644
index 0000000..b8d3573
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/output_utility.lua
@@ -0,0 +1,48 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local setmetatable = setmetatable
+local assert, loadstring = assert, loadstring
+
+module("json.encode.output_utility")
+
+-- Key == weak, if main key goes away, then cache cleared
+local outputCache = setmetatable({}, {__mode = 'k'})
+-- TODO: inner tables weak?
+
+local function buildFunction(nextValues, innerValue, valueWriter, innerWriter)
+	local putInner = ""
+	if innerValue and innerWriter then
+		-- Prepare the lua-string representation of the separator to put in between values
+		local formattedInnerValue = ("%q"):format(innerValue)
+		-- Fill in the condition %WRITE_INNER% and the %INNER_VALUE% to actually write
+		putInner = innerWriter:gsub("%%WRITE_INNER%%", "%%1"):gsub("%%INNER_VALUE%%", formattedInnerValue)
+	end
+	-- Template-in the value writer (if present) and its conditional argument
+	local functionCode = nextValues:gsub("PUTINNER(%b())", putInner)
+	-- %VALUE% is to be filled in by the value-to-write
+	valueWriter = valueWriter:gsub("%%VALUE%%", "%%1")
+	-- Template-in the value writer with its argument
+	functionCode = functionCode:gsub("PUTVALUE(%b())", valueWriter)
+	functionCode = [[
+		return function(composite, ret, encode, state)
+	]] .. functionCode .. [[
+		end
+	]]
+	return assert(loadstring(functionCode))()
+end
+
+function prepareEncoder(cacheKey, nextValues, innerValue, valueWriter, innerWriter)
+	local cache = outputCache[cacheKey]
+	if not cache then
+		cache = {}
+		outputCache[cacheKey] = cache
+	end
+	local fun = cache[nextValues]
+	if not fun then
+		fun = buildFunction(nextValues, innerValue, valueWriter, innerWriter)
+		cache[nextValues] = fun
+	end
+	return fun
+end
diff --git a/luajson-1.2.1/lua/json/encode/strings.lua b/luajson-1.2.1/lua/json/encode/strings.lua
new file mode 100644
index 0000000..8603305
--- /dev/null
+++ b/luajson-1.2.1/lua/json/encode/strings.lua
@@ -0,0 +1,67 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local string_char = require("string").char
+local pairs = pairs
+
+local util_merge = require("json.util").merge
+module("json.encode.strings")
+
+local normalEncodingMap = {
+	['"'] = '\\"',
+	['\\'] = '\\\\',
+	['/'] = '\\/',
+	['\b'] = '\\b',
+	['\f'] = '\\f',
+	['\n'] = '\\n',
+	['\r'] = '\\r',
+	['\t'] = '\\t',
+	['\v'] = '\\v' -- not in official spec, on report, removing
+}
+
+local xEncodingMap = {}
+for char, encoded in pairs(normalEncodingMap) do
+	xEncodingMap[char] = encoded
+end
+
+-- Pre-encode the control characters to speed up encoding...
+-- NOTE: UTF-8 may not work out right w/ JavaScript
+-- JavaScript uses 2 bytes after a \u... yet UTF-8 is a
+-- byte-stream encoding, not pairs of bytes (it does encode
+-- some letters > 1 byte, but base case is 1)
+for i = 0, 255 do
+	local c = string_char(i)
+	if c:match('[%z\1-\031\128-\255]') and not normalEncodingMap[c] then
+		-- WARN: UTF8 specializes values >= 0x80 as parts of sequences...
+		--       without \x encoding, do not allow encoding > 7F
+		normalEncodingMap[c] = ('\\u%.4X'):format(i)
+		xEncodingMap[c] = ('\\x%.2X'):format(i)
+	end
+end
+
+local defaultOptions = {
+	xEncode = false, -- Encode single-bytes as \xXX
+	-- / is not required to be quoted but it helps with certain decoding
+	-- Required encoded characters, " \, and 00-1F  (0 - 31)
+	encodeSet = '\\"/%z\1-\031',
+	encodeSetAppend = nil -- Chars to append to the default set
+}
+
+default = nil
+strict = nil
+
+function getEncoder(options)
+	options = options and util_merge({}, defaultOptions, options) or defaultOptions
+	local encodeSet = options.encodeSet
+	if options.encodeSetAppend then
+		encodeSet = encodeSet .. options.encodeSetAppend
+	end
+	local encodingMap = options.xEncode and xEncodingMap or normalEncodingMap
+	local function encodeString(s, state)
+		return '"' .. s:gsub('[' .. encodeSet .. ']', encodingMap) .. '"'
+	end
+	return {
+		string = encodeString
+	}
+end
diff --git a/luajson-1.2.1/lua/json/util.lua b/luajson-1.2.1/lua/json/util.lua
new file mode 100644
index 0000000..28e47ea
--- /dev/null
+++ b/luajson-1.2.1/lua/json/util.lua
@@ -0,0 +1,108 @@
+--[[
+	Licensed according to the included 'LICENSE' document
+	Author: Thomas Harning Jr <harningt@gmail.com>
+]]
+local type = type
+local print = print
+local tostring = tostring
+local pairs = pairs
+local getmetatable, setmetatable = getmetatable, setmetatable
+local select = select
+
+module("json.util")
+local function foreach(tab, func)
+	for k, v in pairs(tab) do
+		func(k,v)
+	end
+end
+function printValue(tab, name)
+        local parsed = {}
+        local function doPrint(key, value, space)
+                space = space or ''
+                if type(value) == 'table' then
+                        if parsed[value] then
+                                print(space .. key .. '= <' .. parsed[value] .. '>')
+                        else
+                                parsed[value] = key
+                                print(space .. key .. '= {')
+                                space = space .. ' '
+                                foreach(value, function(key, value) doPrint(key, value, space) end)
+                        end
+                else
+					if type(value) == 'string' then
+						value = '[[' .. tostring(value) .. ']]'
+					end
+					print(space .. key .. '=' .. tostring(value))
+                end
+        end
+        doPrint(name, tab)
+end
+
+function clone(t)
+	local ret = {}
+	for k,v in pairs(t) do
+		ret[k] = v
+	end
+	return ret
+end
+
+local function merge(t, from, ...)
+	if not from then
+		return t
+	end
+	for k,v in pairs(from) do
+		t[k] = v
+	end
+	return merge(t, ...)
+end
+_M.merge = merge
+
+-- Function to insert nulls into the JSON stream
+function null()
+	return null
+end
+
+-- Marker for 'undefined' values
+function undefined()
+	return undefined
+end
+
+local ArrayMT = {}
+
+--[[
+	Return's true if the metatable marks it as an array..
+	Or false if it has no array component at all
+	Otherwise nil to get the normal detection component working
+]]
+function IsArray(value)
+	if type(value) ~= 'table' then return false end
+	local ret = getmetatable(value) == ArrayMT
+	if not ret then
+		if #value == 0 then return false end
+	else
+		return ret
+	end
+end
+function InitArray(array)
+	setmetatable(array, ArrayMT)
+	return array
+end
+
+local CallMT = {}
+
+function isCall(value)
+	return CallMT == getmetatable(value)
+end
+
+function buildCall(name, ...)
+	local callData = {
+		name = name,
+		parameters = {n = select('#', ...), ...}
+	}
+	return setmetatable(callData, CallMT)
+end
+
+function decodeCall(callData)
+	if not isCall(callData) then return nil end
+	return callData.name, callData.parameters
+end
diff --git a/luajson-1.2.1/rockspecs/luajson-0.10-1.rockspec b/luajson-1.2.1/rockspecs/luajson-0.10-1.rockspec
new file mode 100644
index 0000000..efbe14b
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-0.10-1.rockspec
@@ -0,0 +1,43 @@
+package = "luajson"
+version = "0.10-1"
+source = {
+	url = "http://luaforge.net/frs/download.php/3637/luajson-0.10.tar.bz2",
+	md5 = "0b6fa5e3a07daabe79241922b0bfda92"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		json = "src/json.lua",
+		["json.util"] = "src/json/util.lua",
+		["json.decode"] = "src/json/decode.lua",
+		["json.decode.array"] = "src/json/decode/array.lua",
+		["json.decode.calls"] = "src/json/decode/calls.lua",
+		["json.decode.number"] = "src/json/decode/number.lua",
+		["json.decode.object"] = "src/json/decode/object.lua",
+		["json.decode.others"] = "src/json/decode/others.lua",
+		["json.decode.strings"] = "src/json/decode/strings.lua",
+		["json.decode.util"] = "src/json/decode/util.lua",
+		["json.encode"] = "src/json/encode.lua",
+		["json.encode.array"] = "src/json/encode/array.lua",
+		["json.encode.calls"] = "src/json/encode/calls.lua",
+		["json.encode.number"] = "src/json/encode/number.lua",
+		["json.encode.object"] = "src/json/encode/object.lua",
+		["json.encode.others"] = "src/json/encode/others.lua",
+		["json.encode.strings"] = "src/json/encode/strings.lua"
+	}
+}
diff --git a/luajson-1.2.1/rockspecs/luajson-0.10-2.rockspec b/luajson-1.2.1/rockspecs/luajson-0.10-2.rockspec
new file mode 100644
index 0000000..c29df87
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-0.10-2.rockspec
@@ -0,0 +1,43 @@
+package = "luajson"
+version = "0.10-2"
+source = {
+	url = "http://luaforge.net/frs/download.php/3893/luajson-0.10.tar.bz2",
+	md5 = "0b6fa5e3a07daabe79241922b0bfda92"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		json = "src/json.lua",
+		["json.util"] = "src/json/util.lua",
+		["json.decode"] = "src/json/decode.lua",
+		["json.decode.array"] = "src/json/decode/array.lua",
+		["json.decode.calls"] = "src/json/decode/calls.lua",
+		["json.decode.number"] = "src/json/decode/number.lua",
+		["json.decode.object"] = "src/json/decode/object.lua",
+		["json.decode.others"] = "src/json/decode/others.lua",
+		["json.decode.strings"] = "src/json/decode/strings.lua",
+		["json.decode.util"] = "src/json/decode/util.lua",
+		["json.encode"] = "src/json/encode.lua",
+		["json.encode.array"] = "src/json/encode/array.lua",
+		["json.encode.calls"] = "src/json/encode/calls.lua",
+		["json.encode.number"] = "src/json/encode/number.lua",
+		["json.encode.object"] = "src/json/encode/object.lua",
+		["json.encode.others"] = "src/json/encode/others.lua",
+		["json.encode.strings"] = "src/json/encode/strings.lua"
+	}
+}
diff --git a/luajson-1.2.1/rockspecs/luajson-0.9.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-0.9.1-1.rockspec
new file mode 100644
index 0000000..64ba4b6
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-0.9.1-1.rockspec
@@ -0,0 +1,35 @@
+package = "luajson"
+version = "0.9.1-1"
+source = {
+	url = "http://luaforge.net/frs/download.php/3637/luajson-0.9.1.tar.bz2",
+	md5 = "49a6a3b7912a053a2b7ad6bbcf4d3564"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://gitrepo.or.cz/w/luajson.git",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		json = "src/json.lua",
+		["json.util"] = "src/json/util.lua",
+		["json.encode"] = "src/json/encode.lua",
+		["json.decode"] = "src/json/decode.lua",
+		["json.decode.array"] = "src/json/decode/array.lua",
+		["json.decode.number"] = "src/json/decode/number.lua",
+		["json.decode.object"] = "src/json/decode/object.lua",
+		["json.decode.string"] = "src/json/decode/strings.lua",
+		["json.decode.util"] = "src/json/decode/util.lua"
+	}
+}
diff --git a/luajson-1.2.1/rockspecs/luajson-1.0-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.0-1.rockspec
new file mode 100644
index 0000000..143f01d
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-1.0-1.rockspec
@@ -0,0 +1,46 @@
+package = "luajson"
+version = "1.0-1"
+source = {
+	url = "http://luaforge.net/frs/download.php/4105/luajson-1.0.tar.bz2",
+	md5 = "0e3ee192f93d40c4947e828668828e91"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		["json.decode.array"] = "lua/json/decode/array.lua",
+		["json.decode.calls"] = "lua/json/decode/calls.lua",
+		["json.decode.number"] = "lua/json/decode/number.lua",
+		["json.decode.object"] = "lua/json/decode/object.lua",
+		["json.decode.others"] = "lua/json/decode/others.lua",
+		["json.decode.strings"] = "lua/json/decode/strings.lua",
+		["json.decode.util"] = "lua/json/decode/util.lua",
+		["json.decode"] = "lua/json/decode.lua",
+		["json.encode.array"] = "lua/json/encode/array.lua",
+		["json.encode.calls"] = "lua/json/encode/calls.lua",
+		["json.encode.number"] = "lua/json/encode/number.lua",
+		["json.encode.object"] = "lua/json/encode/object.lua",
+		["json.encode.others"] = "lua/json/encode/others.lua",
+		["json.encode.output"] = "lua/json/encode/output.lua",
+		["json.encode.output_utility"] = "lua/json/encode/output_utility.lua",
+		["json.encode.strings"] = "lua/json/encode/strings.lua",
+		["json.encode"] = "lua/json/encode.lua",
+		["json.util"] = "lua/json/util.lua",
+		["json"] = "lua/json.lua"
+	}
+}
+
diff --git a/luajson-1.2.1/rockspecs/luajson-1.0.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.0.1-1.rockspec
new file mode 100644
index 0000000..35584dc
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-1.0.1-1.rockspec
@@ -0,0 +1,46 @@
+package = "luajson"
+version = "1.0.1-1"
+source = {
+	url = "http://luaforge.net/frs/download.php/4311/luajson-1.0.1.tar.bz2",
+	md5 = "f6d52689e0bc4cbbfffff29308e78812"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		["json"] = "lua/json.lua",
+		["json.decode"] = "lua/json/decode.lua",
+		["json.decode.array"] = "lua/json/decode/array.lua",
+		["json.decode.calls"] = "lua/json/decode/calls.lua",
+		["json.decode.number"] = "lua/json/decode/number.lua",
+		["json.decode.object"] = "lua/json/decode/object.lua",
+		["json.decode.others"] = "lua/json/decode/others.lua",
+		["json.decode.strings"] = "lua/json/decode/strings.lua",
+		["json.decode.util"] = "lua/json/decode/util.lua",
+		["json.encode"] = "lua/json/encode.lua",
+		["json.encode.array"] = "lua/json/encode/array.lua",
+		["json.encode.calls"] = "lua/json/encode/calls.lua",
+		["json.encode.number"] = "lua/json/encode/number.lua",
+		["json.encode.object"] = "lua/json/encode/object.lua",
+		["json.encode.others"] = "lua/json/encode/others.lua",
+		["json.encode.output"] = "lua/json/encode/output.lua",
+		["json.encode.output_utility"] = "lua/json/encode/output_utility.lua",
+		["json.encode.strings"] = "lua/json/encode/strings.lua",
+		["json.util"] = "lua/json/util.lua"
+	}
+}
+
diff --git a/luajson-1.2.1/rockspecs/luajson-1.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.1-1.rockspec
new file mode 100644
index 0000000..5be6026
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-1.1-1.rockspec
@@ -0,0 +1,46 @@
+package = "luajson"
+version = "1.1-1"
+source = {
+	url = "http://luaforge.net/frs/download.php/4312/luajson-1.1.tar.bz2",
+	md5 = "9c4d267b7383b54576ed307e451aefa4"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		["json"] = "lua/json.lua",
+		["json.decode"] = "lua/json/decode.lua",
+		["json.decode.array"] = "lua/json/decode/array.lua",
+		["json.decode.calls"] = "lua/json/decode/calls.lua",
+		["json.decode.number"] = "lua/json/decode/number.lua",
+		["json.decode.object"] = "lua/json/decode/object.lua",
+		["json.decode.others"] = "lua/json/decode/others.lua",
+		["json.decode.strings"] = "lua/json/decode/strings.lua",
+		["json.decode.util"] = "lua/json/decode/util.lua",
+		["json.encode"] = "lua/json/encode.lua",
+		["json.encode.array"] = "lua/json/encode/array.lua",
+		["json.encode.calls"] = "lua/json/encode/calls.lua",
+		["json.encode.number"] = "lua/json/encode/number.lua",
+		["json.encode.object"] = "lua/json/encode/object.lua",
+		["json.encode.others"] = "lua/json/encode/others.lua",
+		["json.encode.output"] = "lua/json/encode/output.lua",
+		["json.encode.output_utility"] = "lua/json/encode/output_utility.lua",
+		["json.encode.strings"] = "lua/json/encode/strings.lua",
+		["json.util"] = "lua/json/util.lua"
+	}
+}
+
diff --git a/luajson-1.2.1/rockspecs/luajson-1.2-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.2-1.rockspec
new file mode 100644
index 0000000..10755c3
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-1.2-1.rockspec
@@ -0,0 +1,46 @@
+package = "luajson"
+version = "1.2-1"
+source = {
+	url = "http://luaforge.net/frs/download.php/4672/luajson-1.2.tar.bz2",
+	md5 = "a80aa3c2d96d73afbf63f7146857e116"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		["json"] = "lua/json.lua",
+		["json.decode"] = "lua/json/decode.lua",
+		["json.decode.array"] = "lua/json/decode/array.lua",
+		["json.decode.calls"] = "lua/json/decode/calls.lua",
+		["json.decode.number"] = "lua/json/decode/number.lua",
+		["json.decode.object"] = "lua/json/decode/object.lua",
+		["json.decode.others"] = "lua/json/decode/others.lua",
+		["json.decode.strings"] = "lua/json/decode/strings.lua",
+		["json.decode.util"] = "lua/json/decode/util.lua",
+		["json.encode"] = "lua/json/encode.lua",
+		["json.encode.array"] = "lua/json/encode/array.lua",
+		["json.encode.calls"] = "lua/json/encode/calls.lua",
+		["json.encode.number"] = "lua/json/encode/number.lua",
+		["json.encode.object"] = "lua/json/encode/object.lua",
+		["json.encode.others"] = "lua/json/encode/others.lua",
+		["json.encode.output"] = "lua/json/encode/output.lua",
+		["json.encode.output_utility"] = "lua/json/encode/output_utility.lua",
+		["json.encode.strings"] = "lua/json/encode/strings.lua",
+		["json.util"] = "lua/json/util.lua"
+	}
+}
+
diff --git a/luajson-1.2.1/rockspecs/luajson-1.2.1-1.rockspec b/luajson-1.2.1/rockspecs/luajson-1.2.1-1.rockspec
new file mode 100644
index 0000000..7ec8805
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-1.2.1-1.rockspec
@@ -0,0 +1,44 @@
+package = "luajson"
+version = "1.2.1-1"
+source = {
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		["json"] = "lua/json.lua",
+		["json.decode"] = "lua/json/decode.lua",
+		["json.decode.array"] = "lua/json/decode/array.lua",
+		["json.decode.calls"] = "lua/json/decode/calls.lua",
+		["json.decode.number"] = "lua/json/decode/number.lua",
+		["json.decode.object"] = "lua/json/decode/object.lua",
+		["json.decode.others"] = "lua/json/decode/others.lua",
+		["json.decode.strings"] = "lua/json/decode/strings.lua",
+		["json.decode.util"] = "lua/json/decode/util.lua",
+		["json.encode"] = "lua/json/encode.lua",
+		["json.encode.array"] = "lua/json/encode/array.lua",
+		["json.encode.calls"] = "lua/json/encode/calls.lua",
+		["json.encode.number"] = "lua/json/encode/number.lua",
+		["json.encode.object"] = "lua/json/encode/object.lua",
+		["json.encode.others"] = "lua/json/encode/others.lua",
+		["json.encode.output"] = "lua/json/encode/output.lua",
+		["json.encode.output_utility"] = "lua/json/encode/output_utility.lua",
+		["json.encode.strings"] = "lua/json/encode/strings.lua",
+		["json.util"] = "lua/json/util.lua"
+	}
+}
+
diff --git a/luajson-1.2.1/rockspecs/luajson-scm-1.rockspec b/luajson-1.2.1/rockspecs/luajson-scm-1.rockspec
new file mode 100644
index 0000000..e54a7f4
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-scm-1.rockspec
@@ -0,0 +1,34 @@
+package = "luajson"
+version = "scm-1"
+source = {
+	url = "git://repo.or.cz/luajson.git"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://gitrepo.or.cz/w/luajson.git",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		json = "src/json.lua",
+		["json.util"] = "src/json/util.lua",
+		["json.encode"] = "src/json/encode.lua",
+		["json.decode"] = "src/json/decode.lua",
+		["json.decode.array"] = "src/json/decode/array.lua",
+		["json.decode.number"] = "src/json/decode/number.lua",
+		["json.decode.object"] = "src/json/decode/object.lua",
+		["json.decode.string"] = "src/json/decode/strings.lua",
+		["json.decode.util"] = "src/json/decode/util.lua"
+	}
+}
diff --git a/luajson-1.2.1/rockspecs/luajson-scm-2.rockspec b/luajson-1.2.1/rockspecs/luajson-scm-2.rockspec
new file mode 100644
index 0000000..471195c
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-scm-2.rockspec
@@ -0,0 +1,42 @@
+package = "luajson"
+version = "scm-1"
+source = {
+	url = "git://github.com/harningt/luajson.git"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		json = "src/json.lua",
+		["json.util"] = "src/json/util.lua",
+		["json.decode"] = "src/json/decode.lua",
+		["json.decode.array"] = "src/json/decode/array.lua",
+		["json.decode.calls"] = "src/json/decode/calls.lua",
+		["json.decode.number"] = "src/json/decode/number.lua",
+		["json.decode.object"] = "src/json/decode/object.lua",
+		["json.decode.others"] = "src/json/decode/others.lua",
+		["json.decode.strings"] = "src/json/decode/strings.lua",
+		["json.decode.util"] = "src/json/decode/util.lua",
+		["json.encode"] = "src/json/encode.lua",
+		["json.encode.array"] = "src/json/encode/array.lua",
+		["json.encode.calls"] = "src/json/encode/calls.lua",
+		["json.encode.number"] = "src/json/encode/number.lua",
+		["json.encode.object"] = "src/json/encode/object.lua",
+		["json.encode.others"] = "src/json/encode/others.lua",
+		["json.encode.strings"] = "src/json/encode/strings.lua"
+	}
+}
diff --git a/luajson-1.2.1/rockspecs/luajson-scm-3.rockspec b/luajson-1.2.1/rockspecs/luajson-scm-3.rockspec
new file mode 100644
index 0000000..ad6147f
--- /dev/null
+++ b/luajson-1.2.1/rockspecs/luajson-scm-3.rockspec
@@ -0,0 +1,45 @@
+package = "luajson"
+version = "scm-3"
+source = {
+	url = "git://github.com/harningt/luajson.git"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+		["json.decode.array"] = "lua/json/decode/array.lua",
+		["json.decode.calls"] = "lua/json/decode/calls.lua",
+		["json.decode.number"] = "lua/json/decode/number.lua",
+		["json.decode.object"] = "lua/json/decode/object.lua",
+		["json.decode.others"] = "lua/json/decode/others.lua",
+		["json.decode.strings"] = "lua/json/decode/strings.lua",
+		["json.decode.util"] = "lua/json/decode/util.lua",
+		["json.decode"] = "lua/json/decode.lua",
+		["json.encode.array"] = "lua/json/encode/array.lua",
+		["json.encode.calls"] = "lua/json/encode/calls.lua",
+		["json.encode.number"] = "lua/json/encode/number.lua",
+		["json.encode.object"] = "lua/json/encode/object.lua",
+		["json.encode.others"] = "lua/json/encode/others.lua",
+		["json.encode.output"] = "lua/json/encode/output.lua",
+		["json.encode.output_utility"] = "lua/json/encode/output_utility.lua",
+		["json.encode.strings"] = "lua/json/encode/strings.lua",
+		["json.encode"] = "lua/json/encode.lua",
+		["json.util"] = "lua/json/util.lua",
+		["json"] = "lua/json.lua"
+	}
+}
+
diff --git a/luajson-1.2.1/tests/data.txt b/luajson-1.2.1/tests/data.txt
new file mode 100644
index 0000000..7ae4f34
--- /dev/null
+++ b/luajson-1.2.1/tests/data.txt
@@ -0,0 +1 @@
+{"a317":null,"a50":50,"a108":true,"a482":482,"a397":null,"a228":true,"a193":null,"a58":58,"a71":[],"a2":2,"a376":true,"a46":46,"a337":null,"a366":366,"a239":[],"a347":[],"a388":true,"a424":true,"a386":386,"a387":[],"a81":null,"a49":null,"a60":true,"a496":true,"a346":346,"a497":null,"a328":true,"a370":370,"a427":[],"a194":194,"a269":null,"a354":354,"a265":null,"a454":454,"a276":true,"a494":494,"a96":true,"a392":true,"a492":true,"a273":null,"a339":[],"a491":[],"a490":490,"a266":266,"a37":null,"a489":null,"a447":[],"a488":true,"a487":[],"a486":486,"a278":278,"a149":null,"a59":[],"a103":[],"a153":null,"a395":[],"a357":null,"a483":[],"a481":null,"a480":true,"a51":[],"a479":[],"a299":[],"a127":[],"a123":[],"a467":[],"a475":[],"a474":474,"a173":null,"a82":82,"a165":null,"a244":true,"a375":[],"a472":true,"a377":null,"a471":[],"a83":[],"a147":[],"a87":[],"a456":true,"a315":[],"a145":null,"a249":null,"a406":406,"a40":true,"a29":null,"a468":true,"a114":114,"a128":true,"a409":null,"a355":[],"a293":null,"a48":true,"a476":true,"a227":[],"a466":466,"a267":[],"a465":null,"a464":true,"a463":[],"a92":true,"a237":null,"a76":true,"a462":462,"a461":null,"a275":[],"a139":[],"a460":true,"a247":[],"a97":null,"a459":[],"a174":174,"a458":458,"a415":[],"a172":true,"a457":null,"a301":null,"a295":[],"a39":[],"a34":34,"a291":[],"a116":true,"a202":202,"a255":[],"a200":true,"a433":null,"a35":[],"a407":[],"a470":470,"a212":true,"a126":126,"a292":true,"a62":62,"a134":134,"a321":null,"a455":[],"a222":222,"a143":[],"a175":[],"a136":true,"a198":198,"a63":[],"a120":true,"a67":[],"a452":true,"a437":null,"a450":450,"a156":true,"a195":[],"a201":null,"a44":true,"a449":null,"a155":[],"a391":[],"a89":null,"a105":null,"a351":[],"a300":true,"a28":true,"a45":null,"a135":[],"a426":426,"a1":null,"a448":true,"a144":true,"a72":true,"a340":true,"a56":true,"a446":446,"a125":null,"a90":90,"a182":182,"a73":null,"a343":[],"a211":[],"a444":true,"a443":[],"a442":442,"a245":null,"a441":null,"a440":true,"a15":[],"a439":[],"a364":true,"a402":402,"a246":246,"a132":true,"a99":[],"a14":14,"a451":[],"a324":true,"a91":[],"a78":78,"a176":true,"a382":382,"a109":null,"a435":[],"a434":434,"a66":66,"a110":110,"a166":166,"a336":true,"a422":422,"a432":true,"a431":[],"a47":[],"a190":190,"a43":[],"a430":430,"a356":true,"a283":[],"a429":null,"a25":null,"a361":null,"a428":true,"a80":true,"a69":null,"a305":null,"a146":146,"a196":true,"a333":null,"a24":true,"a425":null,"a500":true,"a3":[],"a423":[],"a186":186,"a88":true,"a421":null,"a36":true,"a350":350,"a52":true,"a389":null,"a171":[],"a236":true,"a325":null,"a411":[],"a298":298,"a57":null,"a204":true,"a181":null,"a349":null,"a418":418,"a138":138,"a169":null,"a417":null,"a416":true,"a414":414,"a413":null,"a79":[],"a319":[],"a412":true,"a124":true,"a75":[],"a394":394,"a384":true,"a408":true,"a118":118,"a405":null,"a268":true,"a231":[],"a279":[],"a27":[],"a404":true,"a23":[],"a306":306,"a271":[],"a401":null,"a289":null,"a400":true,"a150":150,"a399":[],"a398":398,"a22":22,"a238":238,"a281":null,"a396":true,"a84":true,"a484":true,"a393":null,"a493":null,"a390":390,"a178":178,"a419":[],"a85":null,"a5":null,"a133":null,"a499":[],"a218":218,"a162":162,"a368":true,"a235":[],"a379":[],"a410":410,"a260":true,"a383":[],"a436":true,"a33":null,"a335":[],"a371":[],"a141":null,"a290":290,"a220":true,"a380":true,"a32":true,"a338":338,"a381":null,"a142":142,"a374":374,"a140":true,"a373":null,"a372":true,"a119":[],"a101":null,"a205":null,"a197":null,"a55":[],"a159":[],"a495":[],"a261":null,"a187":[],"a129":null,"a30":30,"a318":318,"a369":null,"a329":null,"a223":[],"a160":true,"a158":158,"a252":true,"a148":true,"a121":null,"a304":true,"a241":null,"a365":null,"a26":26,"a438":438,"a168":true,"a111":[],"a363":[],"a64":true,"a362":362,"a360":true,"a151":[],"a216":true,"a219":[],"a21":null,"a191":[],"a100":true,"a65":null,"a359":[],"a7":[],"a192":true,"a312":true,"a102":102,"a188":true,"a234":234,"a131":[],"a189":null,"a17":null,"a353":null,"a112":true,"a352":true,"a13":null,"a420":true,"a348":true,"a313":null,"a179":[],"a122":122,"a345":null,"a12":true,"a344":true,"a18":18,"a342":342,"a251":[],"a303":[],"a341":null,"a378":378,"a334":334,"a157":null,"a130":130,"a332":true,"a331":[],"a330":330,"a10":10,"a367":[],"a327":[],"a326":326,"a323":[],"a322":322,"a225":null,"a86":86,"a316":true,"a177":null,"a314":314,"a358":358,"a311":[],"a185":null,"a310":310,"a309":null,"a217":null,"a206":206,"a115":[],"a164":true,"a240":true,"a208":true,"a403":[],"a302":302,"a9":null,"a257":null,"a478":478,"a297":null,"a296":true,"a294":294,"a161":null,"a307":[],"a287":[],"a286":286,"a285":null,"a20":true,"a284":true,"a282":282,"a280":true,"a485":null,"a152":true,"a277":null,"a274":274,"a272":true,"a270":270,"a264":true,"a263":[],"a77":null,"a106":106,"a154":154,"a167":[],"a215":[],"a308":true,"a98":98,"a94":94,"a70":70,"a74":74,"a11":[],"a256":true,"a254":254,"a253":null,"a19":[],"a207":[],"a95":[],"a262":262,"a250":250,"a248":true,"a184":true,"a243":[],"a242":242,"a385":null,"a41":null,"a233":null,"a68":true,"a232":true,"a230":230,"a229":null,"a209":null,"a226":226,"a320":true,"a224":true,"a16":true,"a221":null,"a54":54,"a117":null,"a113":null,"a38":38,"a259":[],"a137":null,"a214":214,"a213":null,"a183":[],"a469":null,"a107":[],"a163":[],"a61":null,"a93":null,"a42":42,"a453":null,"a203":[],"a199":[],"a445":null,"a31":[],"a210":210,"a6":6,"a477":null,"a258":258,"a104":true,"a4":true,"a180":true,"a498":498,"a170":170,"a473":null,"a288":true,"a8":true,"a53":null}
diff --git a/luajson-1.2.1/tests/dataTest.lua b/luajson-1.2.1/tests/dataTest.lua
new file mode 100644
index 0000000..f59421c
--- /dev/null
+++ b/luajson-1.2.1/tests/dataTest.lua
@@ -0,0 +1,11 @@
+local io = require("io")
+require("json")
+local f = io.open("data.txt")
+local data = f:read('*a')
+f:close()
+local opt = (...)
+local strict = opt and opt:match('--strict')
+local decode = json.decode.decode
+for i = 1,1000 do
+	decode(data, strict)
+end
diff --git a/luajson-1.2.1/tests/dataTest.php b/luajson-1.2.1/tests/dataTest.php
new file mode 100644
index 0000000..8bdddac
--- /dev/null
+++ b/luajson-1.2.1/tests/dataTest.php
@@ -0,0 +1,5 @@
+<?php
+	$data = file_get_contents('data.txt');
+	for($i = 0; $i < 1000; $i++)
+		$v = json_decode($data);
+?>
diff --git a/luajson-1.2.1/tests/hook_require.lua b/luajson-1.2.1/tests/hook_require.lua
new file mode 100644
index 0000000..4853c38
--- /dev/null
+++ b/luajson-1.2.1/tests/hook_require.lua
@@ -0,0 +1,15 @@
+local os = require("os")
+local old_require = require
+if os.getenv('LUA_OLD_INIT') then
+	assert(loadstring(os.getenv('LUA_OLD_INIT')))()
+else
+	require("luarocks.require")
+end
+local luarocks_require = require
+
+function require(module, ...)
+	if module == "json" or module:match("^json%.") then
+		return old_require(module, ...)
+	end
+	return luarocks_require(module, ...)
+end
diff --git a/luajson-1.2.1/tests/lunit-calls.lua b/luajson-1.2.1/tests/lunit-calls.lua
new file mode 100644
index 0000000..2c7a65b
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-calls.lua
@@ -0,0 +1,171 @@
+local json = require("json")
+local lunit = require("lunit")
+local math = require("math")
+local testutil = require("testutil")
+
+local encode = json.encode
+-- DECODE NOT 'local' due to requirement for testutil to access it
+decode = json.decode.getDecoder(false)
+
+module("lunit-calls", lunit.testcase, package.seeall)
+
+function setup()
+	-- Ensure that the decoder is reset
+	_G["decode"] = json.decode.getDecoder(false)
+end
+
+local values = {
+	0,
+	1,
+	0.2,
+	"Hello",
+	true,
+	{hi=true},
+	{1,2}
+}
+
+function test_identity()
+	local function testFunction(capturedName, ...)
+		assert_equal('call', capturedName)
+		return (...)
+	end
+	local strict = {
+		calls = { defs = {
+			call = testFunction
+		} }
+	}
+	local decode = json.decode.getDecoder(strict)
+	for i, v in ipairs(values) do
+		local str = "call(" .. encode(v) .. ")"
+		local decoded = decode(str)
+		if type(decoded) == 'table' then
+			for k2, v2 in pairs(v) do
+				assert_equal(v2, decoded[k2])
+				decoded[k2] = nil
+			end
+			assert_nil(next(decoded))
+		else
+			assert_equal(v, decoded)
+		end
+	end
+end
+
+-- Test for a function that throws
+function test_function_failure()
+	local function testFunction(...)
+		error("CANNOT CONTINUE")
+	end
+	local strict = {
+		calls = { defs = {
+			call = testFunction
+		} }
+	}
+	local decode = json.decode.getDecoder(strict)
+	for i, v in ipairs(values) do
+		local str = "call(" .. encode(v) .. ")"
+		assert_error(function()
+			decode(str)
+		end)
+	end
+end
+
+-- Test for a function that is not a function
+function test_not_a_function_fail()
+	local notFunction = {
+		0/0, 1/0, -1/0, 0, 1, "Hello", {}, coroutine.create(function() end)
+	}
+	for _, v in ipairs(notFunction) do
+		assert_error(function()
+			local strict = {
+				calls = { defs = {
+					call = v
+				}, allowUndefined = false }
+			}
+			json.decode.getDecoder(strict)
+		end)
+	end
+end
+
+function test_not_permitted_fail()
+	local strict = {
+		calls = {
+			defs = { call = false }
+		}
+	}
+	local decoder = json.decode.getDecoder(strict)
+	assert_error(function()
+		decoder("call(1)")
+	end)
+end
+
+function test_permitted()
+	local strict = {
+		calls = {
+			defs = { call = true }
+		}
+	}
+	local decoder = json.decode.getDecoder(strict)
+	assert(decoder("call(1)").name == 'call')
+end
+
+function test_not_defined_fail()
+	local decoder = json.decode.getDecoder({
+		calls = {
+			allowUndefined = false
+		}
+	})
+	assert_error(function()
+		decoder("call(1)")
+	end)
+end
+
+function test_not_defined_succeed()
+	local decoder = json.decode.getDecoder({
+		calls = {
+			allowUndefined = true
+		}
+	})
+	assert(decoder("call(1)").name == 'call')
+end
+
+-- Test for a name that is not a string
+function test_name_not_string()
+	local notString = {
+		true, false, 0/0, 1/0, -1/0, 0, 1, {}, function() end, coroutine.create(function() end)
+	}
+	for _, v in ipairs(notString) do
+		assert_error(function()
+			local defs = {
+				[v] = function() end
+			}
+			local strict = {
+				calls = { defs = defs }
+			}
+			json.decode.getDecoder(strict)
+		end)
+	end
+end
+
+-- Test for a name that is a string or a pattern
+function test_name_matches_string_or_pattern()
+	local matchedValues = {
+		["mystring"] = "mystring",
+		[lpeg.C(lpeg.P("m") * (lpeg.P("y") + lpeg.P("Y")) * "string")] = "mystring",
+		[lpeg.C(lpeg.P("m") * (lpeg.P("y") + lpeg.P("Y")) * "string")] = "mYstring"
+	}
+	for pattern, value in pairs(matchedValues) do
+		local matched = false
+		local function mustBeCalled(capturedName, ...)
+			assert_equal(value, capturedName)
+			matched = true
+		end
+		matched = false
+		local strict = {
+			calls = { defs = {
+				[pattern] = mustBeCalled
+			} }
+		}
+		json.decode.getDecoder(strict)(value .. "(true)")
+		assert_true(matched, "Value <" .. value .. "> did not match the given pattern")
+	end
+end
diff --git a/luajson-1.2.1/tests/lunit-encoderfunc.lua b/luajson-1.2.1/tests/lunit-encoderfunc.lua
new file mode 100644
index 0000000..c07c764
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-encoderfunc.lua
@@ -0,0 +1,30 @@
+local json = require("json")
+local lunit = require("lunit")
+local math = require("math")
+local testutil = require("testutil")
+
+local setmetatable = setmetatable
+
+module("lunit-encoderfunc", lunit.testcase, package.seeall)
+
+local function build_call(name, parameters)
+	return json.util.buildCall(name, unpack(parameters, parameters.n))
+end
+
+function test_param_counts()
+	local encoder = json.encode.getEncoder()
+	assert(encoder(build_call('noparam', {})))
+	assert(encoder(build_call('oneparam', {1})))
+	assert(encoder(build_call('multiparam', {1,2})))
+end
+
+function test_output()
+	local encoder = json.encode.getEncoder()
+	assert_equal('b64("hello")', encoder(build_call('b64', {'hello'})))
+	assert_equal('add(1,2)', encoder(build_call('add', {1,2})))
+	assert_equal('dood([b64("hello"),add(1,2)])',
+		encoder(build_call('dood', { {
+			build_call('b64', {'hello'}),
+			build_call('add', {1,2})
+		} })))
+end
diff --git a/luajson-1.2.1/tests/lunit-encoding.lua b/luajson-1.2.1/tests/lunit-encoding.lua
new file mode 100644
index 0000000..bdeb1c2
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-encoding.lua
@@ -0,0 +1,52 @@
+local json = require("json")
+local lunit = require("lunit")
+
+module("lunit-encoding", lunit.testcase, package.seeall)
+
+function test_cloned_array_sibling()
+	local obj = {}
+	assert_pass(function()
+		json.encode({obj, obj})
+	end)
+end
+
+function test_cloned_object_sibling()
+	local obj = {}
+	assert_pass(function()
+		json.encode({x = obj, y = obj})
+	end)
+end
+
+function test_cloned_array_deep_sibling()
+	local obj = {}
+	assert_pass(function()
+		json.encode({
+			{obj}, {obj}
+		})
+	end)
+end
+
+function test_cloned_array_multilevel_sibling()
+	local obj = {}
+	assert_pass(function()
+		json.encode({
+			{obj, {obj}}
+		})
+	end)
+end
+
+function test_recursive_object()
+	local obj = {}
+	obj.x = obj
+	assert_error(function()
+		json.encode(obj)
+	end)
+end
+
+function test_recursive_array()
+	local obj = {}
+	obj[1] = obj
+	assert_error(function()
+		json.encode(obj)
+	end)
+end
diff --git a/luajson-1.2.1/tests/lunit-numbers.lua b/luajson-1.2.1/tests/lunit-numbers.lua
new file mode 100644
index 0000000..2d42fd7
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-numbers.lua
@@ -0,0 +1,151 @@
+local json = require("json")
+local lunit = require("lunit")
+local math = require("math")
+local testutil = require("testutil")
+local string = require("string")
+
+local encode = json.encode
+-- DECODE NOT 'local' due to requirement for testutil to access it
+decode = json.decode.getDecoder(false)
+
+module("lunit-numbers", lunit.testcase, package.seeall)
+
+function setup()
+	-- Ensure that the decoder is reset
+	_G["decode"] = json.decode.getDecoder(false)
+end
+
+local function assert_near(expect, received)
+	local pctDiff
+	if expect == received then
+		pctDiff = 0
+	else
+		pctDiff = math.abs(1 - expect / received)
+	end
+	local msg = ("expected '%s' but was '%s' .. '%s'%% apart"):format(expect, received, pctDiff * 100)
+	assert(pctDiff < 0.000001, msg)
+end
+local function test_simple(num)
+	assert_near(num, decode(tostring(num)))
+end
+local function test_simple_w_encode(num)
+	assert_near(num, decode(encode(num)))
+end
+local function test_scientific(num)
+	assert_near(num, decode(string.format('%e', num)))
+	assert_near(num, decode(string.format('%E', num)))
+end
+local numbers = {
+	0, 1, -1, math.pi, -math.pi
+}
+math.randomseed(0xDEADBEEF)
+-- Add sequence of numbers at low/high end of value-set
+for i = -300,300,60 do
+	numbers[#numbers + 1] = math.random() * math.pow(10, i)
+	numbers[#numbers + 1] = -math.random() * math.pow(10, i)
+end
+
+local function get_number_tester(f)
+	return function ()
+		for _, v in ipairs(numbers) do
+			f(v)
+		end
+	end
+end
+
+test_simple_numbers = get_number_tester(test_simple)
+test_simple_numbers_w_encode = get_number_tester(test_simple_w_encode)
+test_simple_numbers_scientific = get_number_tester(test_scientific)
+
+function test_infinite_nostrict()
+	assert_equal(math.huge, decode("Infinity"))
+	assert_equal(math.huge, decode("infinity"))
+	assert_equal(-math.huge, decode("-Infinity"))
+	assert_equal(-math.huge, decode("-infinity"))
+end
+
+function test_nan_nostrict()
+	local value = decode("nan")
+	assert_true(value ~= value)
+	local value = decode("NaN")
+	assert_true(value ~= value)
+end
+
+function test_expression()
+	assert_error(function()
+		decode("1 + 2")
+	end)
+end
+
+-- For strict tests, small concession must be made to allow non-array/objects as root
+local strict = json.util.merge({}, json.decode.strict, {initialObject = false})
+local strictDecoder = json.decode.getDecoder(strict)
+
+local numberValue = {hex = true}
+
+local hex = {number = numberValue}
+local hexDecoder = json.decode.getDecoder(hex)
+
+function test_hex()
+	if decode == hexDecoder then -- MUST SKIP FAIL UNTIL BETTER METHOD SETUP
+		return
+	end
+	assert_error(function()
+		decode("0x20")
+	end)
+end
+
+local hexNumbers = {
+	0xDEADBEEF,
+	0xCAFEBABE,
+	0x00000000,
+	0xFFFFFFFF,
+	0xCE,
+	0x01
+}
+
+function test_hex_only()
+	_G["decode"] = hexDecoder
+	for _, v in ipairs(hexNumbers) do
+		assert_equal(v, decode(("0x%x"):format(v)))
+		assert_equal(v, decode(("0X%X"):format(v)))
+		assert_equal(v, decode(("0x%X"):format(v)))
+		assert_equal(v, decode(("0X%x"):format(v)))
+	end
+end
+
+local decimal_hexes = {
+	"0x0.1",
+	"0x.1",
+	"0x0e+1",
+	"0x0E-1"
+}
+function test_no_decimal_hex_only()
+	for _, str in ipairs(decimal_hexes) do
+		assert_error(function()
+			hexDecoder(str)
+		end)
+	end
+end
+
+function test_nearly_scientific_hex_only()
+	assert_equal(0x00E1, hexDecoder("0x00e1"))
+end
+
+local function buildStrictDecoder(f)
+	return testutil.buildPatchedDecoder(f, strictDecoder)
+end
+local function buildFailedStrictDecoder(f)
+	return testutil.buildFailedPatchedDecoder(f, strictDecoder)
+end
+-- SETUP CHECKS FOR SEQUENCE OF DECODERS
+for k, v in pairs(_M) do
+	if k:match("^test_") and not k:match("_gen$") and not k:match("_only$") then
+		if k:match("_nostrict") then
+			_M[k .. "_strict_gen"] = buildFailedStrictDecoder(v)
+		else
+			_M[k .. "_strict_gen"] = buildStrictDecoder(v)
+		end
+		_M[k .. "_hex_gen"] = testutil.buildPatchedDecoder(v, hexDecoder)
+	end
+end
diff --git a/luajson-1.2.1/tests/lunit-simple-decode.lua b/luajson-1.2.1/tests/lunit-simple-decode.lua
new file mode 100644
index 0000000..73c4c45
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-simple-decode.lua
@@ -0,0 +1,65 @@
+local json = require("json")
+local lunit = require("lunit")
+
+-- Test module for handling the simple decoding that behaves more like expected
+module("lunit-simple-decode", lunit.testcase, package.seeall)
+
+function test_decode_simple_undefined()
+	assert_nil(json.decode('undefined', json.decode.simple))
+end
+function test_decode_default_undefined()
+	assert_equal(json.util.undefined, json.decode('undefined'))
+end
+
+function test_decode_simple_null()
+	assert_nil(json.decode('null', json.decode.simple))
+end
+
+function test_decode_default_null()
+	assert_equal(json.util.null, json.decode('null'))
+end
+
+function test_decode_array_simple_with_null()
+	local result = assert(json.decode('[1, null, 3]', json.decode.simple))
+	assert_equal(1, result[1])
+	assert_nil(result[2])
+	assert_equal(3, result[3])
+	assert_equal(3, result.n)
+end
+
+function test_decode_array_default_with_null()
+	local result = assert(json.decode('[1, null, 3]'))
+	assert_equal(1, result[1])
+	assert_equal(json.util.null, result[2])
+	assert_equal(3, result[3])
+	assert_equal(3, #result)
+end
+
+function test_decode_object_simple_with_null()
+	local result = assert(json.decode('{x: null}', json.decode.simple))
+	assert_nil(result.x)
+	assert_nil(next(result))
+end
+
+function test_decode_object_default_with_null()
+	local result = assert(json.decode('{x: null}'))
+	assert_equal(json.util.null, result.x)
+	assert_not_nil(next(result))
+end
+
+function test_decode_object_with_stringized_numeric_keys_default()
+	local result = assert(json.decode('{"1": "one"}'))
+	assert_equal("one", result["1"])
+	assert_equal(nil, result[1])
+end
+
+function test_decode_object_with_stringized_numeric_keys_force_numeric()
+	local result = assert(
+			json.decode(
+					'{"1": "one"}',
+					{ object = { setObjectKey = assert(json.decode.util.setObjectKeyForceNumber) } }
+				)
+		)
+	assert_equal(nil, result["1"])
+	assert_equal("one", result[1])
+end
diff --git a/luajson-1.2.1/tests/lunit-strings.lua b/luajson-1.2.1/tests/lunit-strings.lua
new file mode 100644
index 0000000..305df16
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-strings.lua
@@ -0,0 +1,168 @@
+local json = require("json")
+local lunit = require("lunit")
+local testutil = require("testutil")
+local string= require("string")
+
+local encode = json.encode
+-- DECODE NOT 'local' due to requirement for testutil to access it
+decode = json.decode.getDecoder(false)
+
+local error = error
+
+module("lunit-strings", lunit.testcase, package.seeall)
+
+local function assert_table_equal(expect, t)
+	if type(expect) ~= 'table' then
+		return assert_equal(expect, t)
+	end
+	for k,v in pairs(expect) do
+		if type(k) ~= 'string' and type(k) ~= 'number' and type(k) ~= 'boolean' then
+			error("INVALID expected table key")
+		end
+		local found = t[k]
+		if found == nil then
+			fail(tostring(k) .. " not found but expected")
+		end
+		assert_table_equal(v, t[k])
+	end
+	for k,v in pairs(t) do
+		if nil == expect[k] then
+			fail(tostring(k) .. " found but not expected")
+		end
+	end
+end
+
+function setup()
+	-- Ensure that the decoder is reset
+	_G["decode"] = json.decode.getDecoder(false)
+end
+
+function test_strict_quotes()
+	local opts = {
+		strings = {
+			strict_quotes = true
+		}
+	}
+	assert_error(function()
+		local decoder = json.decode.getDecoder(opts)
+		decoder("'hello'")
+	end)
+	opts.strings.strict_quotes = false
+	assert_equal("hello", json.decode.getDecoder(opts)("'hello'"))
+	-- Quote test
+	assert_equal("he'\"llo'", json.decode.getDecoder(opts)("'he\\'\"llo\\''"))
+
+end
+
+local utf16_matches = {
+	-- 1-byte
+	{ '"\\u0000"', string.char(0x00) },
+	{ '"\\u007F"', string.char(0x7F) },
+	-- 2-byte
+	{ '"\\u0080"', string.char(0xC2, 0x80) },
+	{ '"\\u00A2"', string.char(0xC2, 0xA2) },
+	{ '"\\u07FF"', string.char(0xDF, 0xBF) },
+	-- 3-byte
+	{ '"\\u0800"', string.char(0xE0, 0xA0, 0x80) },
+	{ '"\\u20AC"', string.char(0xE2, 0x82, 0xAC) },
+	{ '"\\uFEFF"', string.char(0xEF, 0xBB, 0xBF) },
+	{ '"\\uFFFF"', string.char(0xEF, 0xBF, 0xBF) }
+}
+
+function test_utf16_decode()
+	for i, v in ipairs(utf16_matches) do
+		-- Test that the default \u decoder outputs UTF8
+		local num = tostring(i) .. ' '
+		assert_equal(num .. v[2], num .. json.decode(v[1]))
+	end
+end
+
+local BOM = string.char(0xEF, 0xBB, 0xBF)
+-- BOM skipping tests - here due to relation to UTF8/16
+local BOM_skip_tests = {
+	{ BOM .. '"x"', "x" },
+	{ BOM .. '["\\uFFFF",true]', { string.char(0xEF, 0xBF, 0xBF), true } },
+	-- Other uses of unicode spaces
+}
+
+function test_bom_skip()
+	for i,v in ipairs(BOM_skip_tests) do
+		assert_table_equal(v[2], json.decode(v[1]))
+	end
+end
+
+-- Unicode whitespace codepoints gleaned from unicode.org
+local WHITESPACES = {
+	"\\u0009", -- \t
+	"\\u000A", -- \n
+	"\\u000B", -- \v
+	"\\u000C", -- \f
+	"\\u000D", -- \r
+	"\\u0020", -- space
+	"\\u0085",
+	"\\u00A0",
+	"\\u1680",
+	"\\u180E",
+	"\\u2000",
+	"\\u2001",
+	"\\u2002",
+	"\\u2003",
+	"\\u2004",
+	"\\u2005",
+	"\\u2006",
+	"\\u2007",
+	"\\u2008",
+	"\\u2009",
+	"\\u200A",
+	"\\u200B", -- addition, zero-width space
+	"\\u2028",
+	"\\u2029",
+	"\\u202F",
+	"\\u205F",
+	"\\u3000",
+	"\\uFEFF" -- Zero-width non-breaking space (BOM)
+}
+
+local inject_ws_values = {
+	"%WS%true",
+	" %WS%'the%WS blob'  %WS%",
+	"%WS%{ key: %WS%\"valueMan\",%WS% key2:%WS%4.4}",
+	"%WS%false%WS%"
+}
+function test_whitespace_ignore()
+	for _, ws in ipairs(WHITESPACES) do
+		ws = json.decode('"' .. ws .. '"')
+		for _, v in ipairs(inject_ws_values) do
+			v = v:gsub("%%WS%%", ws)
+			assert_true(nil ~= json.decode(v))
+		end
+	end
+end
+
+function test_u_encoding()
+	local encoder = json.encode.getEncoder()
+	local decoder = json.decode.getDecoder()
+	for i = 0, 255 do
+		local char = string.char(i)
+		assert_equal(char, decoder(encoder(char)))
+	end
+end
+
+function test_x_encoding()
+	local encoder = json.encode.getEncoder({ strings = { xEncode = true } })
+	local decoder = json.decode.getDecoder()
+	for i = 0, 255 do
+		local char = string.char(i)
+		assert_equal(char, decoder(encoder(char)))
+	end
+end
+
+function test_strict_decoding()
+	local encoder = json.encode.getEncoder(json.encode.strict)
+	local decoder = json.decode.getDecoder(json.decode.strict)
+	for i = 0, 255 do
+		local char = string.char(i)
+		-- Must wrap character in array due to decoder strict-ness
+		assert_equal(char, decoder(encoder({char}))[1])
+	end
+end
diff --git a/luajson-1.2.1/tests/lunit-tests.lua b/luajson-1.2.1/tests/lunit-tests.lua
new file mode 100644
index 0000000..30e82df
--- /dev/null
+++ b/luajson-1.2.1/tests/lunit-tests.lua
@@ -0,0 +1,55 @@
+local json = require("json")
+local lunit = require("lunit")
+local testutil = require("testutil")
+-- DECODE NOT 'local' due to requirement for testutil to access it
+decode = json.decode.getDecoder(false)
+
+module("lunit-tests", lunit.testcase, package.seeall)
+
+function setup()
+	_G["decode"] = json.decode.getDecoder(false)
+end
+
+function test_array_empty()
+	local ret = assert_table(decode("[]"))
+	assert_equal(0, #ret)
+	assert_nil(next(ret))
+end
+
+function test_array_trailComma_nostrict()
+	local ret = assert_table(decode("[true,]"))
+	assert_equal(true, ret[1])
+	assert_nil(next(ret, 1))
+	assert_equal(1, #ret)
+end
+
+function test_array_innerComma()
+	assert_error(function()
+		decode("[true,,true]")
+	end)
+end
+
+function test_preprocess()
+	assert_equal('"Hello"', json.encode(1, {preProcess = function() return "Hello" end}))
+	assert_equal('-1', json.encode(1, {preProcess = function(x) return -x end}))
+	assert_equal('-Infinity', json.encode(1/0, {preProcess = function(x) return -x end}))
+end
+
+local strictDecoder = json.decode.getDecoder(true)
+
+local function buildStrictDecoder(f)
+	return testutil.buildPatchedDecoder(f, strictDecoder)
+end
+local function buildFailedStrictDecoder(f)
+	return testutil.buildFailedPatchedDecoder(f, strictDecoder)
+end
+-- SETUP CHECKS FOR SEQUENCE OF DECODERS
+for k, v in pairs(_M) do
+	if k:match("^test_") and not k:match("_gen$") then
+		if k:match("_nostrict") then
+			_M[k .. "_strict_gen"] = buildFailedStrictDecoder(v)
+		else
+			_M[k .. "_strict_gen"] = buildStrictDecoder(v)
+		end
+	end
+end
diff --git a/luajson-1.2.1/tests/regressionTest.lua b/luajson-1.2.1/tests/regressionTest.lua
new file mode 100644
index 0000000..e5711a6
--- /dev/null
+++ b/luajson-1.2.1/tests/regressionTest.lua
@@ -0,0 +1,114 @@
+-- Additional path that may be required
+require("json")
+local io = require("io")
+local os = require("os")
+
+require("lfs")
+
+local success = true
+
+local function getFileData(fileName)
+	local f = io.open(fileName, 'rb')
+	if not f then return end
+	local data = f:read('*a')
+	f:close()
+	return data
+end
+
+local function putTempData(data)
+	local name = os.tmpname()
+	local f = assert(io.open(name, 'wb'))
+	f:write(data)
+	f:close()
+	return name
+end
+
+-- Ensure that the encoder/decoder can round-trip valid JSON
+local function RoundTripTest(parseFunc, encodeFunc, jsonData, luaData, fullRoundTrip, failRoundTrip)
+	local success, dataString = pcall(encodeFunc, luaData)
+	if failRoundTrip then
+		assert(not success, "Round trip encoding test result not as expected")
+		return true
+	else
+		assert(success, "Couldn't encode the lua data..." .. tostring(dataString))
+	end
+	local success, result = pcall(parseFunc, dataString)
+	if not success then
+		print("Could not parse the generated JSON of (", luaData)
+		print("GENERATED: [[" .. dataString .. "]]")
+		print("DATA STORED IN: ", putTempData(dataString))
+		return
+	end
+	if fullRoundTrip then
+		-- Ensure that whitespace is trimmed off ends
+		dataString = dataString:match("^[%s]*(.-)[%s]*$")
+		jsonData = jsonData:match("^[%s]*(.-)[%s]*$")
+		if dataString ~= jsonData then
+			print("Encoded values do not match")
+			print("ORIGINAL: << " .. jsonData .. " >>")
+			print("RE-ENCOD: << " .. dataString .. " >>")
+			return
+		end
+	end
+	return true
+end
+
+local function testFile(fileName, parseFunc, encodeFunc, expectSuccess, fullRoundTrip, failRoundTrip)
+	local data = getFileData(fileName)
+	if not data then return end
+	io.write(".")
+	local succeed, result = pcall(parseFunc, data)
+	if expectSuccess ~= succeed then
+		print("Wrongly " .. (expectSuccess and "Failed" or "Succeeded") .. " on : " .. fileName .. "(" .. tostring(result) .. ")")
+		success = false
+	elseif succeed then
+		if not RoundTripTest(parseFunc, encodeFunc, data, result, fullRoundTrip, failRoundTrip) then
+			print("FAILED TO ROUND TRIP: " .. fileName)
+			success = false
+		end
+	end
+end
+
+local function testDirectories(parseFunc, encodeFunc, directories, ...)
+	if not directories then return end
+	for _,directory in ipairs(directories) do
+		if lfs.attributes(directory, 'mode') == 'directory' then
+			for f in lfs.dir(directory) do
+				testFile(directory .. "/" .. f, parseFunc, encodeFunc, ...)
+			end
+		end
+	end
+	io.write("\n")
+end
+
+local function TestParser(parseFunc, encodeFunc, successNames, failNames, roundTripNames)
+	testDirectories(parseFunc, encodeFunc, successNames, true, false)
+	testDirectories(parseFunc, encodeFunc, failNames, false, false)
+	testDirectories(parseFunc, encodeFunc, roundTripNames, true, true)
+end
+print("Testing lax/fast mode:")
+TestParser(json.decode.getDecoder(), json.encode.getEncoder(), {"test/pass","test/fail_strict"}, {"test/fail_all"},{"test/roundtrip","test/roundtrip_lax"})
+
+print("Testing (mostly) strict mode:")
+local strict = json.util.merge({}, json.decode.strict, {
+	number = {
+		nan = false,
+		inf = true,
+		strict = true
+	}
+})
+local strict_encode = json.util.merge({}, json.encode.strict, {
+	number = {
+		nan = false,
+		inf = true,
+		strict = true
+	}
+})
+TestParser(json.decode.getDecoder(strict), json.encode.getEncoder(strict_encode), {"test/pass"}, {"test/fail_strict","test/fail_all"}, {"test/roundtrip"})
+
+print("Testing (mostly) strict encoder with non-strict decodings")
+testDirectories(json.decode.getDecoder(), json.encode.getEncoder(json.encode.strict), {"test/fail_strict_encode"}, true, true, true)
+
+if not success then
+	os.exit(1)
+end
diff --git a/luajson-1.2.1/tests/test.lua b/luajson-1.2.1/tests/test.lua
new file mode 100644
index 0000000..c5162f5
--- /dev/null
+++ b/luajson-1.2.1/tests/test.lua
@@ -0,0 +1,71 @@
+-- Additional path that may be required
+require("json")
+
+local testStrings = {
+	[[{1:[1213.3e12, 123 , 123, "hello", [12, 2], {1:true /*test*/}]}]],
+	[[{"username":"demo1","message":null,"password":""}]],
+	[[{"challenge":"b64d-fnNQ6bRZ7CYiNIKwmdHoNgl9JR9MIYtzjBhpQzYXCFrgARt9mNmgUuO7FoODGr1NieT9yTeB2SLztGkvIA4NXmN9Bi27hqx1ybJIQq6S2L-AjQ3VTDClSmCsYFPOm9EMVZDZ0jhBX1fXw3o9VYj1j9KzSY5VCSAzGqYo-cBPY\n.b64","cert":"b64MIIGyjCCBbKgAwIBAgIKFAC1ZgAAAAAUYzANBgkqhkiG9w0BAQUFADBZMRUwEwYKCZImiZPyLGQBGRYFbG9tp8uQuFjWGS_KxTHXz9vkLNFjOoZY2bOwzsdEpshuYSdvX-9bRvHTQcoMNz8Q9nXG1aMl5x1nbV5byQNTCJlz4gzMJeNfeKGcipdCj7B6e_VpF-n2P-dFZizUHjxMksCVZ3nTr51x3Uw\n.b64","key":"D79B30BA7954DF520B44897A6FF58919"}]],
+	[[{"key":"D79B30BA7954DF520B44897A6FF58919"}]],
+	[[{"val":undefined}]],
+	[[{
+	"Image": {
+		"Width":  800,
+		"Height": 600,
+		"Title":  "View from 15th Floor",
+		"Thumbnail": {
+			"Url":    "http://www.example.com/image/481989943",
+			"Height": 125,
+			"Width":  "100"
+		},
+		"IDs": [116, 943, 234, 38793]
+	}
+}]],
+	[[ [
+      {
+         "precision": "zip",
+         "Latitude":  37.7668,
+         "Longitude": -122.3959,
+         "Address":   "",
+         "City":      "SAN FRANCISCO",
+         "State":     "CA",
+         "Zip":       "94107",
+         "Country":   "US"
+      },
+      {
+         "precision": "zip",
+         "Latitude":  37.371991,
+         "Longitude": -122.026020,
+         "Address":   "",
+         "City":      "SUNNYVALE",
+         "State":     "CA",
+         "Zip":       "94085",
+         "Country":   "US"
+      }
+   ] ]],
+	[[[null,true,[1,2,3],"hello\"],[world!"] ]],
+	[[ [{"0":"tan\\\\","model\\\\":"sedan"},{"0":"red","model":"sports"}] ]],
+	[[ {"1":"one","2":"two","5":"five"} ]],
+	[=[ [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] ]=]
+}
+
+for i, v in ipairs(testStrings) do
+	print("Testing: #" .. i)
+	local dec = json.decode(v)
+	json.util.printValue(dec, "JSONVALUE")
+	local reenc = json.encode(dec)
+	print("RE_ENC: ", reenc)
+	local redec = json.decode(reenc)
+	json.util.printValue(redec, "REDECJSONVALUE")
+end
+
+local testValues = {
+	{[300] = {nil, true, 1,2,3, nil, 3}}
+}
+
+for _, v in ipairs(testValues) do
+	local ret = json.encode(v)
+	print(ret)
+	local dec = json.decode(ret)
+	json.util.printValue(dec, "Encoded value")
+	print("Re-encoded", json.encode(dec))
+end
diff --git a/luajson-1.2.1/tests/test/fail_all/colonInArray.json b/luajson-1.2.1/tests/test/fail_all/colonInArray.json
new file mode 100644
index 0000000..a775258
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/colonInArray.json
@@ -0,0 +1 @@
+["Colon instead of comma": false]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/commaAfterValue.json b/luajson-1.2.1/tests/test/fail_all/commaAfterValue.json
new file mode 100644
index 0000000..8a96af3
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/commaAfterValue.json
@@ -0,0 +1 @@
+["Comma after the close"],
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/doubleColon.json b/luajson-1.2.1/tests/test/fail_all/doubleColon.json
new file mode 100644
index 0000000..27c1af3
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/doubleColon.json
@@ -0,0 +1 @@
+{"Double colon":: null}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/extraArrayClose.json b/luajson-1.2.1/tests/test/fail_all/extraArrayClose.json
new file mode 100644
index 0000000..b28479c
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/extraArrayClose.json
@@ -0,0 +1 @@
+["Extra close"]]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/extraValueAfterClose.json b/luajson-1.2.1/tests/test/fail_all/extraValueAfterClose.json
new file mode 100644
index 0000000..5d8c004
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/extraValueAfterClose.json
@@ -0,0 +1 @@
+{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/functionExpression.json b/luajson-1.2.1/tests/test/fail_all/functionExpression.json
new file mode 100644
index 0000000..77580a4
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/functionExpression.json
@@ -0,0 +1 @@
+{"Illegal invocation": alert()}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/hexNumber.json b/luajson-1.2.1/tests/test/fail_all/hexNumber.json
new file mode 100644
index 0000000..0ed366b
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/hexNumber.json
@@ -0,0 +1 @@
+{"Numbers cannot be hex": 0x14}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/lineBreakInString-escaped.json b/luajson-1.2.1/tests/test/fail_all/lineBreakInString-escaped.json
new file mode 100644
index 0000000..621a010
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/lineBreakInString-escaped.json
@@ -0,0 +1,2 @@
+["line\
+break"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/mathExpression.json b/luajson-1.2.1/tests/test/fail_all/mathExpression.json
new file mode 100644
index 0000000..76eb95b
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/mathExpression.json
@@ -0,0 +1 @@
+{"Illegal expression": 1 + 2}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/missingArrayValue.json b/luajson-1.2.1/tests/test/fail_all/missingArrayValue.json
new file mode 100644
index 0000000..ed91580
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/missingArrayValue.json
@@ -0,0 +1 @@
+[   , "<-- missing value"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/missingColon.json b/luajson-1.2.1/tests/test/fail_all/missingColon.json
new file mode 100644
index 0000000..3b9c46f
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/missingColon.json
@@ -0,0 +1 @@
+{"Missing colon" null}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/missingColon2.json b/luajson-1.2.1/tests/test/fail_all/missingColon2.json
new file mode 100644
index 0000000..6247457
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/missingColon2.json
@@ -0,0 +1 @@
+{"Comma instead of colon", null}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/octalEscape.json b/luajson-1.2.1/tests/test/fail_all/octalEscape.json
new file mode 100644
index 0000000..62b9214
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/octalEscape.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \017"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/octalNumber.json b/luajson-1.2.1/tests/test/fail_all/octalNumber.json
new file mode 100644
index 0000000..379406b
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/octalNumber.json
@@ -0,0 +1 @@
+{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/tabInString-escaped.json b/luajson-1.2.1/tests/test/fail_all/tabInString-escaped.json
new file mode 100644
index 0000000..845d26a
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/tabInString-escaped.json
@@ -0,0 +1 @@
+["tab\   character\   in\  string\  "]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/trailingDoubleComma.json b/luajson-1.2.1/tests/test/fail_all/trailingDoubleComma.json
new file mode 100644
index 0000000..ddf3ce3
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/trailingDoubleComma.json
@@ -0,0 +1 @@
+["double extra comma",,]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/unclosed_array.json b/luajson-1.2.1/tests/test/fail_all/unclosed_array.json
new file mode 100644
index 0000000..6b7c11e
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/unclosed_array.json
@@ -0,0 +1 @@
+["Unclosed array"
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_all/unknownLiteral.json b/luajson-1.2.1/tests/test/fail_all/unknownLiteral.json
new file mode 100644
index 0000000..494add1
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_all/unknownLiteral.json
@@ -0,0 +1 @@
+["Bad value", truth]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/hexEscape.json b/luajson-1.2.1/tests/test/fail_strict/hexEscape.json
new file mode 100644
index 0000000..fc8376b
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/hexEscape.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \x15"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/lineBreakInString.json b/luajson-1.2.1/tests/test/fail_strict/lineBreakInString.json
new file mode 100644
index 0000000..6b01a2c
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/lineBreakInString.json
@@ -0,0 +1,2 @@
+["line
+break"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/mustBeArrayOrObject.json b/luajson-1.2.1/tests/test/fail_strict/mustBeArrayOrObject.json
new file mode 100644
index 0000000..6216b86
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/mustBeArrayOrObject.json
@@ -0,0 +1 @@
+"A JSON payload should be an object or array, not a string."
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/singleQuoteEscape.json b/luajson-1.2.1/tests/test/fail_strict/singleQuoteEscape.json
new file mode 100644
index 0000000..c43ae3c
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/singleQuoteEscape.json
@@ -0,0 +1 @@
+["Illegal backslash escape: \'"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/singleQuotes.json b/luajson-1.2.1/tests/test/fail_strict/singleQuotes.json
new file mode 100644
index 0000000..caff239
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/singleQuotes.json
@@ -0,0 +1 @@
+['single quote']
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/tabInString.json b/luajson-1.2.1/tests/test/fail_strict/tabInString.json
new file mode 100644
index 0000000..0d3456f
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/tabInString.json
@@ -0,0 +1 @@
+["tab	   character   in  string  "]
diff --git a/luajson-1.2.1/tests/test/fail_strict/trailingArrayComma.json b/luajson-1.2.1/tests/test/fail_strict/trailingArrayComma.json
new file mode 100644
index 0000000..9de168b
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/trailingArrayComma.json
@@ -0,0 +1 @@
+["extra comma",]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/trailingObjectComma.json b/luajson-1.2.1/tests/test/fail_strict/trailingObjectComma.json
new file mode 100644
index 0000000..5815574
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/trailingObjectComma.json
@@ -0,0 +1 @@
+{"Extra comma": true,}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/unquotedKey.json b/luajson-1.2.1/tests/test/fail_strict/unquotedKey.json
new file mode 100644
index 0000000..168c81e
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/unquotedKey.json
@@ -0,0 +1 @@
+{unquoted_key: "keys must be quoted"}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict/whitespace_before_value.json b/luajson-1.2.1/tests/test/fail_strict/whitespace_before_value.json
new file mode 100644
index 0000000..51abe00
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict/whitespace_before_value.json
@@ -0,0 +1,2 @@
+
+"test string"
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/bool.json b/luajson-1.2.1/tests/test/fail_strict_encode/bool.json
new file mode 100644
index 0000000..27ba77d
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/bool.json
@@ -0,0 +1 @@
+true
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/inf.json b/luajson-1.2.1/tests/test/fail_strict_encode/inf.json
new file mode 100644
index 0000000..c90da34
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/inf.json
@@ -0,0 +1 @@
+{x: Infinity}
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/nan.json b/luajson-1.2.1/tests/test/fail_strict_encode/nan.json
new file mode 100644
index 0000000..5f497c6
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/nan.json
@@ -0,0 +1 @@
+{x: NaN}
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/null.json b/luajson-1.2.1/tests/test/fail_strict_encode/null.json
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/null.json
@@ -0,0 +1 @@
+null
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/number.json b/luajson-1.2.1/tests/test/fail_strict_encode/number.json
new file mode 100644
index 0000000..29d6383
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/number.json
@@ -0,0 +1 @@
+100
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/string.json b/luajson-1.2.1/tests/test/fail_strict_encode/string.json
new file mode 100644
index 0000000..a0b0c28
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/string.json
@@ -0,0 +1 @@
+"Heloo world"
diff --git a/luajson-1.2.1/tests/test/fail_strict_encode/undefined.json b/luajson-1.2.1/tests/test/fail_strict_encode/undefined.json
new file mode 100644
index 0000000..311eb44
--- /dev/null
+++ b/luajson-1.2.1/tests/test/fail_strict_encode/undefined.json
@@ -0,0 +1 @@
+{x: undefined}
diff --git a/luajson-1.2.1/tests/test/pass/extremeNesting.json b/luajson-1.2.1/tests/test/pass/extremeNesting.json
new file mode 100644
index 0000000..edac927
--- /dev/null
+++ b/luajson-1.2.1/tests/test/pass/extremeNesting.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/pass/pass1.json b/luajson-1.2.1/tests/test/pass/pass1.json
new file mode 100644
index 0000000..7828fcc
--- /dev/null
+++ b/luajson-1.2.1/tests/test/pass/pass1.json
@@ -0,0 +1,56 @@
+[
+    "JSON Test Pattern pass1",
+    {"object with 1 member":["array with 1 element"]},
+    {},
+    [],
+    -42,
+    true,
+    false,
+    null,
+    {
+        "integer": 1234567890,
+        "real": -9876.543210,
+        "e": 0.123456789e-12,
+        "E": 1.234567890E+34,
+        "":  23456789012E666,
+        "zero": 0,
+        "one": 1,
+        "space": " ",
+        "quote": "\"",
+        "backslash": "\\",
+        "controls": "\b\f\n\r\t",
+        "slash": "/ & \/",
+        "alpha": "abcdefghijklmnopqrstuvwyz",
+        "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+        "digit": "0123456789",
+        "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+        "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+        "true": true,
+        "false": false,
+        "null": null,
+        "array":[  ],
+        "object":{  },
+        "address": "50 St. James Street",
+        "url": "http://www.JSON.org/",
+        "comment": "// /* <!-- --",
+        "# -- --> */": " ",
+        " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5        ,          6           ,7        ],
+        "compact": [1,2,3,4,5,6,7],
+        "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+        "quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
+        "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+    },
+    0.5 ,98.6
+,
+99.44
+,
+
+1066
+
+
+,"rosebud"]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/pass/pass3.json b/luajson-1.2.1/tests/test/pass/pass3.json
new file mode 100644
index 0000000..4528d51
--- /dev/null
+++ b/luajson-1.2.1/tests/test/pass/pass3.json
@@ -0,0 +1,6 @@
+{
+    "JSON Test Pattern pass3": {
+        "The outermost value": "must be an object or array.",
+        "In this test": "It is an object."
+    }
+}
diff --git a/luajson-1.2.1/tests/test/pass/stringWithEscapedAndUnescapedSlash.json b/luajson-1.2.1/tests/test/pass/stringWithEscapedAndUnescapedSlash.json
new file mode 100644
index 0000000..4b174a9
--- /dev/null
+++ b/luajson-1.2.1/tests/test/pass/stringWithEscapedAndUnescapedSlash.json
@@ -0,0 +1 @@
+["/ & \/"]
diff --git a/luajson-1.2.1/tests/test/pass/whitespace_before_array.json b/luajson-1.2.1/tests/test/pass/whitespace_before_array.json
new file mode 100644
index 0000000..5a5b662
--- /dev/null
+++ b/luajson-1.2.1/tests/test/pass/whitespace_before_array.json
@@ -0,0 +1 @@
+ [1,2]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/pass/whitespace_before_object.json b/luajson-1.2.1/tests/test/pass/whitespace_before_object.json
new file mode 100644
index 0000000..1e5f843
--- /dev/null
+++ b/luajson-1.2.1/tests/test/pass/whitespace_before_object.json
@@ -0,0 +1 @@
+ {"a":"Whitespace before object"}
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/roundtrip/deepArray.json b/luajson-1.2.1/tests/test/roundtrip/deepArray.json
new file mode 100644
index 0000000..d3c63c7
--- /dev/null
+++ b/luajson-1.2.1/tests/test/roundtrip/deepArray.json
@@ -0,0 +1 @@
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
diff --git a/luajson-1.2.1/tests/test/roundtrip/emptyArray.json b/luajson-1.2.1/tests/test/roundtrip/emptyArray.json
new file mode 100644
index 0000000..fe51488
--- /dev/null
+++ b/luajson-1.2.1/tests/test/roundtrip/emptyArray.json
@@ -0,0 +1 @@
+[]
diff --git a/luajson-1.2.1/tests/test/roundtrip/emptyObject.json b/luajson-1.2.1/tests/test/roundtrip/emptyObject.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/luajson-1.2.1/tests/test/roundtrip/emptyObject.json
@@ -0,0 +1 @@
+{}
diff --git a/luajson-1.2.1/tests/test/roundtrip/simpleArrayInObject.json b/luajson-1.2.1/tests/test/roundtrip/simpleArrayInObject.json
new file mode 100644
index 0000000..63771e7
--- /dev/null
+++ b/luajson-1.2.1/tests/test/roundtrip/simpleArrayInObject.json
@@ -0,0 +1 @@
+{"object with 1 member":["array with 1 element"]}
diff --git a/luajson-1.2.1/tests/testutil.lua b/luajson-1.2.1/tests/testutil.lua
new file mode 100644
index 0000000..66d8595
--- /dev/null
+++ b/luajson-1.2.1/tests/testutil.lua
@@ -0,0 +1,22 @@
+local pcall, error = pcall, error
+
+local lunit = require("lunit")
+local assert_error = lunit.assert_error
+
+-- Allow module to alter decoder
+local function setDecoder(d)
+	decode = d
+end
+module("testutil", package.seeall)
+function buildPatchedDecoder(f, newDecoder)
+	return function()
+		setDecoder(newDecoder)
+		f()
+	end
+end
+function buildFailedPatchedDecoder(f, newDecoder)
+	return function()
+		setDecoder(newDecoder)
+		assert_error(f)
+	end
+end
diff --git a/luajson-1.2.1/tests/timetrials.lua b/luajson-1.2.1/tests/timetrials.lua
new file mode 100644
index 0000000..1ffa121
--- /dev/null
+++ b/luajson-1.2.1/tests/timetrials.lua
@@ -0,0 +1,52 @@
+--[[

+  Some Time Trails for the JSON4Lua package

+]]--

+

+require('json')

+local os = require('os')

+local table = require('table')

+local string = require("string")

+

+local skipDecode = (...) == '--skipDecode'

+local count = tonumber(select(2, ...) or 500) or 500

+local strDup = tonumber(select(3, ...) or 1) or 1

+local t1 = os.clock()

+local jstr

+local v

+for i=1,count do

+  local t = {}

+  for j=1,500 do

+    t[#t + 1] = j

+  end

+  for j=1,500 do

+    t[#t + 1] = string.rep("VALUE", strDup)

+  end

+  jstr = json.encode(t)

+  if not skipDecode then v = json.decode(jstr) end

+  --print(json.encode(t))

+end

+

+for i = 1,count do

+  local t = {}

+  for j=1,500 do

+    local m= j % 4

+    local idx = string.rep('a'..j, strDup)

+    if (m==0) then

+      t[idx] = true

+    elseif m==1 then 

+      t[idx] = json.util.null

+    elseif m==2 then

+      t[idx] = j

+    else

+      t[idx] = string.char(j % 0xFF)

+    end

+  end

+  jstr = json.encode(t)

+  if not skipDecode then v = json.decode(jstr) end

+end

+

+print (jstr)

+--print(type(t1))

+local t2 = os.clock()

+

+print ("Elapsed time=" .. os.difftime(t2,t1) .. "s")

diff --git a/luajson-1.2.1/util/createRock.lua b/luajson-1.2.1/util/createRock.lua
new file mode 100644
index 0000000..d4481c9
--- /dev/null
+++ b/luajson-1.2.1/util/createRock.lua
@@ -0,0 +1,45 @@
+local io = require("io")
+
+local version = assert((...), "Requires rock version on command-line")
+
+local template = [=[
+package = "luajson"
+version = %VERSION%
+source = {
+	url = "git://github.com/harningt/luajson.git"
+}
+description = {
+	summary = "customizable JSON decoder/encoder",
+	detailed = [[
+		LuaJSON is a customizable JSON decoder/encoder using
+		LPEG for parsing.
+	]],
+	homepage = "http://github.com/harningt/luajson",
+	maintainer = "Thomas Harning <harningt@gmail.com>",
+	license = "MIT/X11"
+}
+dependencies = {
+	"lua >= 5.1",
+	"lunit >= 0.4",
+	"lpeg >= 0.8.1"
+}
+build = {
+	type = "module",
+	modules = {
+%MODULES%
+	}
+}
+]=]
+
+local in_modules = io.popen("find lua -type f -name '*.lua' -not -iname '.*' | sort", "r")
+local modules = in_modules:read("*a")
+in_modules:close()
+
+modules = modules:gsub("lua/([^\n]*)%.lua", function(module)
+	return "\t\t[" .. ("%q"):format(module:gsub("/",".")) .. "] = " .. ("%q"):format("lua/" .. module .. ".lua") .. ","
+end)
+local out = template:gsub("%%(.-)%%", {
+	VERSION = ("%q"):format(version),
+	MODULES = modules
+})
+print(out)
diff --git a/luajson-1.2.1/util/prepareNextRelease.lua b/luajson-1.2.1/util/prepareNextRelease.lua
new file mode 100755
index 0000000..842c4be
--- /dev/null
+++ b/luajson-1.2.1/util/prepareNextRelease.lua
@@ -0,0 +1,29 @@
+#!/usr/bin/env lua
+local io = require("io")
+local from, tover = ...
+if not from or not tover then
+	print("Format: prepareNextRelease.lua <from-tag> <tover-tag>")
+	return
+end
+
+local f = assert(io.open("docs/ReleaseNotes-" .. tover .. ".txt", "w"))
+local headLine = "luajson v" .. tover .. " Release Notes"
+f:write(headLine, "\n", ("="):rep(#headLine), "\n\n")
+
+f:write([[
+User Visible Changes
+--------------------
+
+Plans for next release
+----------------------
+
+]])
+local tailLine = "Updates since " .. from
+f:write(tailLine, "\n", ("="):rep(#tailLine), "\n\n")
+
+local data = assert(io.popen("git shortlog " .. from .. "..HEAD | util/processShortlog.lua", "r"))
+local tail = data:read("*a")
+data:close()
+
+f:write(tail)
+f:close()
diff --git a/luajson-1.2.1/util/processShortlog.lua b/luajson-1.2.1/util/processShortlog.lua
new file mode 100755
index 0000000..4149198
--- /dev/null
+++ b/luajson-1.2.1/util/processShortlog.lua
@@ -0,0 +1,44 @@
+#!/usr/bin/env lua
+local io = require("io")
+local table = require("table")
+local authors = {}
+
+local currentAuthor
+
+local function pushValue(t, group, value)
+	local items = t[group] or {}
+	t[group] = items
+	items[#items + 1] = value
+end
+for line in io.lines() do
+	local author = line:match("^(.- %(%d*%):)$")
+	line = line:match("^%s*(.-)%s*$")
+	if author then
+		currentAuthor = authors[author] or {}
+		authors[author] = currentAuthor
+	elseif currentAuthor and #line > 0 then
+		local msg = line:gsub("^%s*","")
+		local group, data = msg:match("^([^:]*[%s]*:)[%s]*(.*)$")
+		if not group then
+			pushValue(currentAuthor, "-ungrouped-", msg)
+		else
+			pushValue(currentAuthor, group, data)
+		end
+	end
+end
+for author, groups in pairs(authors) do
+	print(author)
+	-- SORT GROUPS
+	local sorted = {}
+	for group, groupValues in pairs(groups) do
+		sorted[#sorted + 1] = {group, groupValues}
+	end
+	table.sort(sorted, function(a,b) return a[1] < b[1] end)
+	for _, gv in ipairs(sorted) do
+		local group, groupValues = unpack(gv)
+		print("\t" .. group)
+		for _, entry in ipairs(groupValues) do
+			print("\t\t" .. entry)
+		end
+	end
+end
diff --git a/luajson.tar.bz2 b/luajson.tar.bz2
new file mode 100644
index 0000000..882d43c
--- /dev/null
+++ b/luajson.tar.bz2
Binary files differ
diff --git a/luajson.url b/luajson.url
new file mode 100644
index 0000000..b703b87
--- /dev/null
+++ b/luajson.url
@@ -0,0 +1 @@
+http://luaforge.net/frs/download.php/4676/luajson-1.2.1.tar.bz2
diff --git a/luajson.version b/luajson.version
new file mode 100644
index 0000000..6085e94
--- /dev/null
+++ b/luajson.version
@@ -0,0 +1 @@
+1.2.1